Ticket #8732: kyra2intro_v4.patch

File kyra2intro_v4.patch, 80.1 KB (added by athrxx, 17 years ago)

KYRA: Intro Patch for Kyra 2

  • gui_v2.cpp

     
    6363        int charWidthBackUp = _screen->_charWidth;
    6464       
    6565        _screen->_charWidth = -2;
     66
    6667        if (_flags.gameID == GI_KYRA2)
    6768                _screen->setScreenDim(11);
    6869        else
    6970                _screen->setScreenDim(3);
     71
    7072        int backUpX = _screen->_curDim->sx;
    7173        int backUpY = _screen->_curDim->sy;
    7274        int backUpWidth = _screen->_curDim->w;
     
    101103                        int item = (mouse.y - menuRect.top) / fh;
    102104
    103105                        if (item != selected) {
    104                                 gui_printString(strings[selected], textPos, menuRect.top + selected * fh, 0x80, 0, 5);
    105                                 gui_printString(strings[item], textPos, menuRect.top + item * fh, 0xFF, 0, 5);
     106                                gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0x80 : 0xd7, 0, 5);
     107                                gui_printString(strings[item], textPos, menuRect.top + item * fh, (_flags.gameID == GI_KYRA3) ? 0xFF : 0xd6, 0, 5);
    106108
    107109                                selected = item;
    108110                        }
    109111
    110112                        if (mousePressed) {
    111                                 // TODO: Flash the text
     113                                for (int i = 0; i < 3; i++) {
     114                                        gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0x80 : 0xd7, 0, 5);
     115                                        _screen->updateScreen();
     116                                        _system->delayMillis(50);
     117                                        gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0xFF : 0xd6, 0, 5);
     118                                        _screen->updateScreen();
     119                                        _system->delayMillis(50);
     120                                }
    112121                                command = item;
    113122                                break;
    114123                        }
     
    126135        return command;
    127136}
    128137
    129 void KyraEngine_v2::gui_drawMainMenu(const char * const *strings, int select) {
     138void KyraEngine_v2::gui_drawMainMenu(const char *const *strings, int select) {
    130139        debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_drawMainMenu(%p)", (const void*)strings);
    131         static const uint16 menuTable[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 };
    132        
     140        static const uint16 menuTable2[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 };
     141        static const uint16 menuTable3[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 };
     142        const uint16 *menuTable;
     143
     144        if (_flags.gameID == GI_KYRA3)
     145                menuTable = menuTable3;
     146        else
     147                menuTable = menuTable2;
     148
    133149        int top = _screen->_curDim->sy;
    134150        top += menuTable[1];
    135151       
     
    143159void KyraEngine_v2::gui_drawMainBox(int x, int y, int w, int h, int fill) {
    144160        debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_drawMainBox(%d, %d, %d, %d, %d)", x, y, w, h, fill);
    145161        static const uint8 kyra3ColorTable[] = { 0x16, 0x19, 0x1A, 0x16 };
    146         static const uint8 kyra2ColorTable[] = { 0x0, 0x19, 0x28, 0xc8 };
    147        
     162        static const uint8 kyra2ColorTable[] = {0xd8, 0xda, 0xd9, 0xd8 };
     163
    148164        const uint8 *colorTable;
    149165        if (_flags.gameID == GI_KYRA3)
    150166                colorTable = kyra3ColorTable;
     
    196212}
    197213
    198214} // end of namespace Kyra
     215
  • kyra_v2.cpp

     
    4444        _debugger = 0;
    4545        _screen = 0;
    4646        _text = 0;
     47
     48        _pageBuffer1 = _pageBuffer2 = 0;
     49        _seqProcessedString = 0;
     50        _activeWSA = 0;
     51        _activeText = 0;
     52        _seqWsa = 0;
    4753       
    4854        _gamePlayBuffer = 0;
    4955        _cCodeBuffer = _optionsBuffer = _chapterBuffer = 0;
     
    8389}
    8490
    8591KyraEngine_v2::~KyraEngine_v2() {
     92        seq_uninit();
     93
    8694        delete [] _mouseSHPBuf;
    8795        delete _screen;
    8896        delete _text;
     
    116124        _screen->setAnimBlockPtr(3504);
    117125        _screen->setScreenDim(0);
    118126       
    119         assert(_introStringsSize == 21);
    120         for (int i = 0; i < 21; i++)
    121                 _introStringsDuration[i] = strlen(_introStrings[i]) * 8;
     127        for (int i = 0; i < 33; i++)
     128                _sequenceStringsDuration[i] = strlen(_sequenceStrings[i]) * 8;
    122129       
     130        _abortIntroFlag = false;
     131
     132        _sequenceSoundList = (const char * const *) _sequenceSoundListPC;
     133        _sequenceSoundListSize = _sequenceSoundListPCSize;
     134
    123135        // No mouse display in demo
    124136        if (_flags.isDemo)
    125137                return 0;
     
    136148        return 0;
    137149}
    138150
    139 int KyraEngine_v2::go() {       
     151int KyraEngine_v2::go() {
     152        // TODO move this to a better location, since for ingame we setup
     153        // our soundfile list in KyraEngine_v2::startup for example
     154        // so this should be just used in the sequenceplayer code,
     155        // so maybe move this to KyraEngine_v2::seq_init
    140156        if (_flags.isDemo) {
    141157                static const char *soundFileList[] = {
    142158                        "K2_DEMO",
     
    157173        _res->unloadPakFile("OUTFARM.PAK");
    158174        _res->unloadPakFile("FLYTRAP.PAK");
    159175
    160         //seq_playSequences(kSequenceVirgin, kSequenceWestwood);
    161         mainMenu();
     176        seq_playSequences(kSequenceVirgin, kSequenceZanfaun);
    162177
     178        if (_menuChoice == 1) {
     179                startup();
     180                runLoop();
     181                cleanup();
     182        } else if (_menuChoice == 3) {
     183                // Load Savegame
     184        }
     185
    163186        return 0;
    164187}
    165188
    166 void KyraEngine_v2::mainMenu() {
    167         bool running = true;
    168 
    169         while (running && !_quitFlag) {
    170                 seq_playSequences(kSequenceTitle);
    171                 _screen->showMouse();
    172                
    173                 switch (gui_handleMainMenu()) {
    174                         case 0:
    175                                 _screen->showMouse();
    176 
    177                                 // load just the pak files needed for ingame
    178                                 _res->unloadAllPakFiles();
    179                                 _res->loadFileList("FILEDATA.FDT");
    180 
    181                                 startup();
    182                                 runLoop();
    183                                 cleanup();
    184                                 running = false;
    185                                 break;
    186                         case 1:
    187                                 seq_playSequences(kSequenceOverview, kSequenceZanFaun);
    188                                 break;
    189                         case 2:
    190                                 break;
    191                         case 3:
    192                                 running = false;
    193                                 break;
    194                         default:
    195                                 break;
    196                 }
    197                 _screen->hideMouse();
    198         }
    199 }
    200 
    201189void KyraEngine_v2::startup() {
    202190        _sound->setSoundFileList(_dosSoundFileList, _dosSoundFileListSize);
    203191        _trackMap = _dosTrackMap;
     
    17081696
    17091697} // end of namespace Kyra
    17101698
     1699
  • kyra_v2.h

     
    3636
    3737enum kSequences {
    3838        kSequenceVirgin = 0,
    39         kSequenceWestwood = 1,
    40         kSequenceTitle = 2,
    41         kSequenceOverview = 3,
    42         kSequenceLibrary = 4,
    43         kSequenceHand = 5,
    44         kSequencePoint = 6,
    45         kSequenceZanFaun = 7
     39        kSequenceWestwood,
     40        kSequenceTitle,
     41        kSequenceOverview,
     42        kSequenceLibrary,
     43        kSequenceHand,
     44        kSequencePoint,
     45        kSequenceZanfaun,
     46
     47        kSequenceFunters,
     48        kSequenceFerb,
     49        kSequenceFish,
     50        kSequenceFheep,
     51        kSequenceFarmer,
     52        kSequenceFuards,
     53        kSequenceFirates,
     54        kSequenceFrash,
     55
     56        kSequenceArraySize
    4657};
    4758
     59enum kNestedSequences {
     60        kSequenceFiggle = 0,
     61        kSequenceOver1,
     62        kSequenceOver2,
     63        kSequenceForest,
     64        kSequenceDragon,
     65        kSequenceDarm,
     66        kSequenceLibrary2,
     67        kSequenceLibrary3,
     68        kSequenceMarco,
     69        kSequenceHand1a,
     70        kSequenceHand1b,
     71        kSequenceHand1c,
     72        kSequenceHand2,
     73        kSequenceHand3,
     74        kSequenceHand4
     75};
     76
    4877class WSAMovieV2;
    4978class KyraEngine_v2;
    5079class TextDisplayer_v2;
     
    5685};
    5786
    5887struct ActiveWSA {
     88        int16 flags;
    5989        WSAMovieV2 *movie;
    60         uint16 currentFrame;
     90        uint16 startFrame;
    6191        uint16 endFrame;
    6292        uint16 frameDelay;
     93        int (KyraEngine_v2::*callback)(WSAMovieV2*, int, int, int);
    6394        uint32 nextFrame;
    64         void (KyraEngine_v2::*callback)(int);
     95        uint16 currentFrame;
     96        uint16 lastFrame;
     97        uint16 x;
     98        uint16 y;       
    6599        const SequenceControl *control;
     100        uint16 startupCommand;
     101        uint16 finalCommand;
    66102};
    67103
    68 struct ActiveChat {
     104struct ActiveText {
    69105        uint16 strIndex;
    70106        uint16 x;
    71107        uint16 y;
    72108        int duration;
    73         uint16 field_8;
    74         uint16 startTime;
    75         uint16 field_E;
     109        uint16 width;
     110        uint32 startTime;
     111        int16 textcolor;
    76112};
    77113
    78114struct Sequence {
    79         uint8 type;
    80         const char *filename;
    81         int (KyraEngine_v2::*callback)(int);
    82         uint8 frameDelay;
     115        uint16 flags;
     116        const char * wsaFile;
     117        const char * cpsFile;
     118        uint8 startupCommand;
     119        uint8 finalCommand;
     120        uint16 stringIndex1;
     121        uint16 stringIndex2;
     122        uint16 startFrame;
     123        uint16 numFrames;
     124        uint16 frameDelay;
     125        uint16 xPos;
     126        uint16 yPos;
     127        int (KyraEngine_v2::*callback)(WSAMovieV2*, int, int, int);
    83128        uint16 duration;
    84         uint8 numFrames;
    85         bool timeOut;
    86         bool fadeOut;
    87129};
    88130
     131struct NestedSequence {
     132        uint16 flags;
     133        const char * wsaFile;
     134        uint16 startframe;
     135        uint16 endFrame;
     136        uint16 frameDelay;
     137        int (KyraEngine_v2::*callback)(WSAMovieV2*, int, int, int);
     138        uint16 x;
     139        uint16 y;
     140        const SequenceControl * wsaControl;
     141        uint16 startupCommand;
     142        uint16 finalCommand;
     143        uint16 unk1;
     144};
     145
    89146class KyraEngine_v2 : public KyraEngine {
    90147friend class Debugger_v2;
    91148friend class TextDisplayer_v2;
     
    105162        virtual void gui_initMainMenu() {}
    106163        int gui_handleMainMenu();
    107164        virtual void gui_updateMainMenuAnimation();
    108         void gui_drawMainMenu(const char * const *strings, int select);
     165        void gui_drawMainMenu(const char *const *strings, int select);
    109166        void gui_drawMainBox(int x, int y, int w, int h, int fill);
    110167        bool gui_mainMenuGetInput();
    111168       
    112169        void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...);
    113170
    114         // intro
     171        // intro/outro
    115172        void seq_playSequences(int startSeq, int endSeq = -1);
    116         int seq_introWestwood(int seqNum);
    117         int seq_introTitle(int seqNum);
    118         int seq_introOverview(int seqNum);
    119         int seq_introLibrary(int seqNum);       
    120         int seq_introHand(int seqNum);
    121         int seq_introPoint(int seqNum);
    122         int seq_introZanFaun(int seqNum);
    123173
    124         void seq_introOverviewOver1(int currentFrame);
    125         void seq_introOverviewForest(int currentFrame);
    126         void seq_introOverviewDragon(int currentFrame);
    127         void seq_loadWSA(int wsaNum, const char *filename, int frameDelay, void (KyraEngine_v2::*callback)(int) = 0,
    128                                          const SequenceControl *control = 0 );
     174        int seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm);
     175        int seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm);
     176        int seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm);
     177        int seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm);       
     178        int seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm);
     179        int seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm);
     180        int seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm);
     181
     182        int seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm);
     183        int seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm);
     184        int seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm);
     185        int seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm);
     186        int seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm);
     187        int seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm);
     188        int seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm);
     189        int seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm);
     190        int seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm);
     191        int seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm);
     192        int seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm);
     193        int seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm);
     194
     195        void seq_sequenceCommand(int command);
     196        void seq_loadNestedSequence(int wsaNum, int seqNum);
     197        void seq_nestedSequenceFrame(int command, int wsaNum);
     198        void seq_animatedSubFrame(int srcPage, int dstPage, int delaytime,
     199                int steps, int x, int y, int w, int h, int openClose, int directionFlags);
     200        bool seq_processNextSubFrame(int wsaNum);
     201        void seq_resetActiveWSA(int wsaNum);
    129202        void seq_unloadWSA(int wsaNum);
    130         void seq_playWSAs();
    131         void seq_showChats();
    132         void seq_playIntroChat(uint8 chatNum);
    133         void seq_resetAllChatEntries();
    134         void seq_waitForChatsToFinish();
    135         void seq_setChatEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 unk1);
     203        void seq_processWSAs();
     204        void seq_cmpFadeFrame(const char *cmpFile);
     205       
     206        void seq_playTalkText(uint8 chatNum);
     207        void seq_resetAllTextEntries();
     208        uint32 seq_activeTextsTimeLeft();
     209        void seq_waitForTextsTimeout();
     210        int seq_setTextEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width);
     211        void seq_processText();
     212        char *seq_preprocessString(const char *str, int width);
    136213
    137         void mainMenu();
     214        void seq_init();
     215        void seq_uninit();
    138216
    139217        int init();
    140218        int go();
     
    143221        TextDisplayer_v2 *_text;
    144222        Debugger_v2 *_debugger;
    145223       
    146         ActiveWSA *_activeWSA;
    147         ActiveChat *_activeChat;
    148224        uint8 *_mouseSHPBuf;
    149225
    150226        static const char *_dosSoundFileList[];
     
    696772        int _unk3, _unk4, _unk5;
    697773        bool _unkSceneScreenFlag1;
    698774        bool _unkHandleSceneChangeFlag;
     775
     776        // sequence player
     777        ActiveWSA *_activeWSA;
     778        ActiveText *_activeText;
     779
     780        const char *const *_sequenceSoundList;
     781        int _sequenceSoundListSize;
     782       
     783        static const char *_sequenceSoundListPC[];
     784        static const int _sequenceSoundListPCSize;
     785        static const char *_sequenceStrings[];
     786        static const int _sequenceStringsSize;
     787       
     788        int _sequenceStringsDuration[33];
     789
     790        uint8 *_pageBuffer1;
     791        uint8 *_pageBuffer2;
     792        static const uint8 _seqTextColorPresets[];
     793        char *_seqProcessedString;
     794        WSAMovieV2 *_seqWsa;
     795
     796        bool _abortIntroFlag;
     797        int _menuChoice;
     798
     799        uint32 _seqFrameDelay;
     800        uint32 _seqEndTime;
     801        int _seqFrameCounter;
     802        bool _seqSubframePlaying;
     803        uint8 _seqTextColor[2];
     804       
     805        static const Sequence _sequences[];
     806        static const NestedSequence _nSequences[];
     807        static const SequenceControl _wsaControlLibrary[];
     808        static const SequenceControl _wsaControlHand1b[];
     809        static const SequenceControl _wsaControlHand1c[];
     810        static const SequenceControl _wsaControlHand2[];
     811        static const SequenceControl _wsaControlHand3[];
     812        static const SequenceControl _wsaControlHand4[];
    699813};
    700814
    701815} // end of namespace Kyra
    702816
    703817#endif
    704818
     819
  • screen.cpp

     
    26442644                return;
    26452645        }
    26462646
     2647        const char *ext = filename + strlen(filename) - 3;
    26472648        uint8 compType = srcData[2];
    2648         uint32 imgSize = READ_LE_UINT32(srcData + 4);
     2649        uint32 imgSize = scumm_stricmp(ext, "CMP") ? READ_LE_UINT32(srcData + 4) : READ_LE_UINT16(srcData);
    26492650        uint16 palSize = READ_LE_UINT16(srcData + 8);
    26502651
    26512652        if (palData && palSize) {
  • screen_v2.cpp

     
    3333Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system)
    3434        : Screen(vm, system) {
    3535        _vm = vm;
     36        _wsaFrameAnimBuffer = new uint8[1024];
    3637}
    3738
    3839Screen_v2::~Screen_v2() {
     40        delete [] _wsaFrameAnimBuffer;
    3941}
    4042
    4143void Screen_v2::setScreenDim(int dim) {
     
    6062        }
    6163}
    6264
    63 void Screen_v2::k2IntroFadeToGrey(int delay) {
    64         debugC(9, kDebugLevelScreen, "Screen_v2::k2IntroFadeToGrey(%d)", delay);
     65void Screen_v2::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) {
     66        uint8 tmpPal[768];
    6567
    66         for (int i = 0; i <= 50; ++i) {
    67                 if (i <= 8 || i >= 30) {
    68                         _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
    69                                                       _currentPalette[3 * i + 1] +
    70                                                       _currentPalette[3 * i + 2]) / 3;
    71                         _currentPalette[3 * i + 1] =  _currentPalette[3 * i + 0];
    72                         _currentPalette[3 * i + 2] =  _currentPalette[3 * i + 0];
     68        for (int i = 0; i != lastColor; i++) {
     69                if (flag) {
     70                        int v = ((((srcPal[3 * i] & 0x3f) + (srcPal[3 * i + 1] & 0x3f)
     71                                + (srcPal[3 * i + 2] & 0x3f)) / 3) * factor) / 0x40;
     72                        tmpPal[3 * i] = tmpPal[3 * i + 1] = tmpPal[3 * i + 2] = v & 0xff;
     73                } else {
     74                        int v = (((srcPal[3 * i] & 0x3f) * factor) / 0x40) + addR;
     75                        tmpPal[3 * i] = (v > 0x3f) ? 0x3f : v & 0xff;
     76                        v = (((srcPal[3 * i + 1] & 0x3f) * factor) / 0x40) + addG;
     77                        tmpPal[3 * i + 1] = (v > 0x3f) ? 0x3f : v & 0xff;
     78                        v = (((srcPal[3 * i + 2] & 0x3f) * factor) / 0x40) + addB;
     79                        tmpPal[3 * i + 2] = (v > 0x3f) ? 0x3f : v & 0xff;
    7380                }
    7481        }
    7582
    76         // color 71 is the same in both the overview and closeup scenes
    77         // Converting it to greyscale makes the trees in the closeup look dull
    78         for (int i = 71; i < 200; ++i) {
    79                 _currentPalette[3 * i + 0] = (_currentPalette[3 * i + 0] +
    80                                               _currentPalette[3 * i + 1] +
    81                                               _currentPalette[3 * i + 2]) / 3;
    82                 _currentPalette[3 * i + 1] =  _currentPalette[3 * i + 0];
    83                 _currentPalette[3 * i + 2] =  _currentPalette[3 * i + 0];
     83        for (int i = 0; i < lastColor; i++)
     84                grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor);
     85}
     86
     87void Screen_v2::applyGrayOverlay(int x, int y, int w, int h, int pageNum, const uint8 *grayOverlay) {
     88        uint8 * dst = getPagePtr(pageNum) + y * 320 + x;
     89        while (h--) {
     90                for (int wi = 0; wi < 320; wi++)
     91                        dst[wi] = grayOverlay[dst[wi]];
     92                dst += 320;
    8493        }
    85         fadePalette(_currentPalette, delay);
    86         // Make the font color white again
    87         setPaletteIndex(254, 254, 254, 254);
    8894}
    8995
     96int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) {
     97        int m = 0x7fff;
     98        int r = 0x101;
     99
     100        for (int i = 0; i < numColors; i++) {
     101                int v = paletteEntry[0] - *palette++;
     102                int c = v * v;
     103                v = paletteEntry[1] - *palette++;
     104                c += (v * v);
     105                v = paletteEntry[2] - *palette++;
     106                c += (v * v);
     107
     108                if (c <= m) {
     109                        m = c;
     110                        r = i;
     111                }
     112        }
     113
     114        return r;
     115}
     116
     117void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
     118        int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) {
     119
     120        if (!(w1 || h1 || w2 || h2))
     121                return;
     122
     123        ScreenDim cdm = _screenDimTable[dim];
     124        cdm.sx <<= 3;
     125        cdm.w <<= 3;
     126
     127        int na = 0, nb = 0, nc = w2;
     128       
     129        if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc))
     130                return;
     131
     132        uint8 * src = getPagePtr(srcPage) + y1 * 320;
     133        uint8 * dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320;
     134
     135        int u = -1;
     136
     137        do {
     138                int t = (nb * h1) / h2;
     139                if (t != u) {
     140                        u = t;
     141                        uint8 * s = src + (x1 + t) * 320;
     142                        uint8 * dt = (uint8*) _wsaFrameAnimBuffer;
     143                       
     144                        t = w2 - w1;
     145                        if (!t) {
     146                                memcpy(dt, s, w2);
     147                        } else if (t > 0) {
     148                                if (w1 == 1) {
     149                    memset(dt, *s, w2);
     150                                } else {
     151                                        t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8;
     152                                        int bp = 0;
     153                                        for (int i = 0; i < w1; i++) {
     154                                                int cnt = (t >> 16);
     155                                                bp += (t & 0xffff);
     156                                                if (bp > 0xffff) {
     157                                                        bp -= 0xffff;
     158                                                        cnt++;
     159                                                }
     160                                                memset(dt, *s++, cnt);
     161                                                dt += cnt;                                             
     162                                        }
     163                                }
     164                        } else {
     165                                if (w2 == 1) {
     166                                        *dt = *s;
     167                                } else {
     168                                        t = (((((w1 - w2) & 0xffff) << 8) / w2) & 0xffff) << 8;
     169                                        int bp = 0;
     170                                        for (int i = 0; i < w2; i++) {
     171                                                *dt++ = *s++;
     172                                                bp += (t & 0xffff);
     173                                                if (bp > 0xffff) {
     174                                                        bp -= 0xffff;
     175                                                        s++;
     176                                                }
     177                                                s += (t >> 16);
     178                                        }
     179                                }
     180                        }
     181                }
     182                memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2);
     183                dst += 320;
     184        } while (++nb < h2);   
     185}
     186
     187void Screen_v2::cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW,
     188        int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage) {
     189
     190        if (!(cmpW || cmpH ))
     191                return;
     192
     193        int r1, r2, r3, r4, r5, r6;
     194
     195        int X1 = srcX;
     196        int Y1 = srcY;
     197        int W1 = cmpW;
     198        int H1 = cmpH;
     199
     200        if (!calcBounds(srcW, srcH, X1, Y1, W1, H1, r1, r2, r3))
     201                return;
     202
     203        int X2 = dstX;
     204        int Y2 = dstY;
     205        int W2 = W1;
     206        int H2 = H1;
     207
     208        if (!calcBounds(dstW, dstH, X2, Y2, W2, H2, r4, r5, r6))
     209                return;
     210
     211        uint8 * src = getPagePtr(srcPage) + srcW * (Y1 + r5);
     212        uint8 * dst = getPagePtr(dstPage) + dstW * (Y2 + r2);
     213        uint8 * cmp = getPagePtr(cmpPage);
     214
     215        while (H2--) {         
     216                uint8 * s = src + r4 + X1;
     217                uint8 * d = dst + r1 + X2;
     218
     219                for (int i = 0; i < W2; i++) {
     220                        int ix = (*s++ << 8) + *d;
     221                        *d++ = cmp[ix];
     222                }
     223
     224                src += W1;
     225                dst += W2;
     226        }
     227}
     228
     229bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) {
     230        x2 = 0;
     231        y2 = 0;
     232        w2 = w1;
     233       
     234        int t = x1 + w1;
     235        if (t < 1) {
     236                w1 = h1 = -1;
     237        } else {
     238                if (t <= x1) {
     239                        x2 = w1 - t;
     240                        w1 = t;
     241                        x1 = 0;
     242                }
     243                t = w0 - x1;
     244                if (t < 1) {
     245                        w1 = h1 = -1;
     246                } else {
     247                        if (t <= w1) {
     248                                w1 = t;
     249                        }
     250                        w2 -= w1;
     251                        t = h1 + y1;
     252                        if (t < 1) {
     253                                w1 = h1 = -1;
     254                        } else {
     255                                if (t <= y1) {
     256                                        y2 = h1 - t;
     257                                        h1 = t;
     258                                        y1 = 0;
     259                                }
     260                t = h0 - y1;
     261                                if (t < 1) {
     262                                        w1 = h1 = -1;
     263                                } else {
     264                                        if (t <= h1) {
     265                                                h1 = t;
     266                                        }
     267                                }
     268                        }
     269                }
     270        }
     271
     272        return (w1 == -1) ? false : true;
     273}
     274
    90275void Screen_v2::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
    91276                                                        int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) {
    92277        uint8 *dstPtr = getPagePtr(_curPage);
  • screen_v2.h

     
    4141        virtual void setScreenDim(int dim);
    4242        const ScreenDim *getScreenDim(int dim);
    4343       
    44         // palette handling
    45         void k2IntroFadeToGrey(int delay=0x54);
     44        // sequence player
     45        void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag);
     46        void applyGrayOverlay(int x, int y, int w, int h, int pageNum, const uint8 *grayOverlay);
     47        int findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors);
     48        bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2);
     49        void wsaFrameAnimationStep(int x1, int y1, int x2, int y2,
     50                int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim);
     51        void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage,
     52                int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage);
    4653       
    4754        // screen page handling
    4855        void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
     
    7481       
    7582        static const ScreenDim _screenDimTable[];
    7683        static const int _screenDimTableCount;
     84
     85        uint8 *_wsaFrameAnimBuffer;
    7786       
    7887        // maybe subclass screen for kyra3
    7988        static const ScreenDim _screenDimTableK3[];
  • sequences_v2.cpp

     
    3636
    3737void KyraEngine_v2::seq_playSequences(int startSeq, int endSeq) {
    3838        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playSequences(%i, %i)", startSeq, endSeq);
     39        seq_init();
    3940
    40         _skipFlag = false;
     41        bool allowSkip = (startSeq == kSequenceTitle) ? false : true;
    4142
    4243        if (endSeq == -1)
    4344                endSeq = startSeq;
    4445       
    45         static const Sequence sequences[] = {
    46                 // type, filename, callback, framedelay, duration, numframes, timeOut, fadeOut
    47                 {2, "virgin.cps",   0,                                 100, 0,   1,  true,  true},
    48                 {1, "westwood.wsa", &KyraEngine_v2::seq_introWestwood, 6,   160, 18, true,  true},
    49                 {1, "title.wsa",    &KyraEngine_v2::seq_introTitle,    6,   10,  26, false, false},
    50                 {2, "over.cps",     &KyraEngine_v2::seq_introOverview, 16,  30,  1,  false, true},
    51                 {2, "library.cps",  &KyraEngine_v2::seq_introLibrary,  16,  30,  1,  false, true},
    52                 {2, "hand.cps",     &KyraEngine_v2::seq_introHand,     16,  90,  1,  false, true},
    53                 {1, "point.wsa",    &KyraEngine_v2::seq_introPoint,    16,  30,  1,  false, true},
    54                 {1, "zanfaun.wsa",  &KyraEngine_v2::seq_introZanFaun,  16,  90,  1,  false, true}
    55         };
     46        assert(startSeq >= 0 && endSeq < kSequenceArraySize && startSeq <= endSeq);
    5647
    57         assert(startSeq >= 0 && endSeq < ARRAYSIZE(sequences) && startSeq <= endSeq);
     48        _screen->_charWidth = -2;
    5849
    59         _activeWSA = new ActiveWSA[8];
    60         assert(_activeWSA);     
    6150        memset(_activeWSA, 0, sizeof(ActiveWSA) * 8);
     51        for (int i = 0; i < 8; i++)
     52                _activeWSA[i].flags = -1;
     53                               
    6254
    63         _activeChat = new ActiveChat[10];
    64         assert(_activeChat);   
    65         memset(_activeChat, 0, sizeof(ActiveChat) * 10);
     55        memset(_activeText, 0, sizeof(ActiveText) * 10);
     56        seq_resetAllTextEntries();
    6657
    67         seq_resetAllChatEntries();
    68 
    6958        _screen->hideMouse();
    7059        int oldPage = _screen->setCurPage(2);
    71        
    72         uint8 pal[768];
    73         memset(pal, 0, sizeof(pal));
    74        
    75         for (int i = startSeq; i <= endSeq && !_skipFlag; i++) {
    76                 uint32 seqDelay = 0;
    77                 int seqNum = 0;
    7860
    79                 _screen->setScreenPalette(pal);
     61        for (int i = 0; i < 4; i++)
     62                memset(_screen->getPalette(i), 0, 0x300);
     63
     64        memset(_pageBuffer1, 0, 0xfa00);
     65        memset(_pageBuffer2, 0, 0xfa00);
     66
     67        _seqSubframePlaying = false;
     68         
     69        int seqWsaCurrentFrame = 0;
     70        _seqTextColor[0] = _seqTextColor[1] = 0;       
     71        _seqEndTime = 0;
     72        _menuChoice = 0;
     73
     74        for (int seqNum = startSeq; seqNum <= endSeq && !((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice); seqNum++) {
    8075                _screen->clearPage(0);
     76                _screen->clearPage(8);
     77        memcpy(_screen->getPalette(1), _screen->getPalette(0), 0x300);                         
     78                _seqFrameCounter = 0;
    8179
    82                 if (sequences[i].type == 2) {
    83                         _screen->loadBitmap(sequences[i].filename, 2, 2, _screen->_currentPalette);
    84                         _screen->updateScreen();
    85                         seqDelay = sequences[i].frameDelay * _tickLength;
    86                 } else if (sequences[i].type == 1) {
    87                         seq_loadWSA(0, sequences[i].filename, sequences[i].frameDelay);
    88                         seqDelay = sequences[i].duration * _tickLength;
     80                allowSkip = (seqNum == 2) ? false : true;
     81               
     82                if (_sequences[seqNum].flags & 2) {
     83                        _screen->loadBitmap(_sequences[seqNum].cpsFile, 2, 2, _screen->getPalette(0));
     84                } else {
     85                        _screen->setCurPage(2);
     86                        _screen->clearPage(2);
     87                        _screen->loadPalette("goldfont.col", _screen->getPalette(0));
    8988                }
    9089
    91                 if (sequences[i].callback)
    92                         (*this.*sequences[i].callback)(seqNum++);
     90                if (_sequences[seqNum].callback)
     91                        (this->*_sequences[seqNum].callback)(0, 0, 0, -1);
    9392
    94                 seq_playWSAs();
    95                 _screen->copyPage(2, 0);
    96                 _screen->updateScreen();
    97                 _screen->fadeFromBlack(40);
     93                if (_sequences[seqNum].flags & 1) {
     94                        if (_seqWsa->opened())
     95                                _seqWsa->close();
     96                        _seqWsa->open(_sequences[seqNum].wsaFile, 0, _screen->getPalette(0));
     97                        _seqWsa->setX(_sequences[seqNum].xPos);
     98                        _seqWsa->setY(_sequences[seqNum].yPos);
     99                        _seqWsa->setDrawPage(2);
     100                        _seqWsa->displayFrame(0, 0);
     101                }
    98102
    99                 seqDelay += _system->getMillis();
    100                 bool mayEndLoop = sequences[i].timeOut;
     103                if (_sequences[seqNum].flags & 4) {
     104                        int cp = _screen->setCurPage(2);
     105                        Screen::FontId cf =     _screen->setFont(Screen::FID_GOLDFONT_FNT);
     106                        int sX = (320 - _screen->getTextWidth(_sequenceStrings[_sequences[seqNum].stringIndex1])) >> 1;                 
     107                        _screen->printText(_sequenceStrings[_sequences[seqNum].stringIndex1], sX, 100 - _screen->getFontHeight(), 1, 0);
     108                        sX = (320 - _screen->getTextWidth(_sequenceStrings[_sequences[seqNum].stringIndex2])) >> 1;                     
     109                        _screen->printText(_sequenceStrings[_sequences[seqNum].stringIndex2], sX, 100, 1, 0);
     110
     111                        _screen->setFont(cf);
     112                        _screen->setCurPage(cp);
     113                }
     114
     115                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     116                _screen->copyPage(0, 2);
     117                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer1);
     118                _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
    101119               
    102                 // Skip the movie if esc is pressed or the mouse is clicked
    103                 // However, don't skip the menu movie, to match the behavior of the original interpreter
    104                 while ((!_quitFlag && !_skipFlag) || i == kSequenceTitle) {
    105                         uint32 startTime = _system->getMillis();
     120                _screen->copyPage(2, 6);
     121               
     122                seq_sequenceCommand(_sequences[seqNum].startupCommand);
     123               
     124                if (!((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     125                        _screen->copyPage(2, 0);
     126                        _screen->updateScreen();
     127                }               
     128
     129                if (_sequences[seqNum].flags & 1) {
     130                        int w2 = _seqWsa->width();
     131                        int h2 = _seqWsa->height();
     132                        int x = _sequences[seqNum].xPos;
     133                        int y = _sequences[seqNum].yPos;
     134
     135                        _seqFrameDelay = _sequences[seqNum].frameDelay;
     136
     137                        if (_seqWsa) {
     138                                if (x < 0) {
     139                                        x = 0;
     140                                        w2 = 0;
     141                                }
     142
     143                                if (y < 0) {
     144                                        y = 0;
     145                                        h2 = 0;
     146                                }
     147
     148                                if (_sequences[seqNum].xPos + _seqWsa->width() > 0x13F)
     149                                        _seqWsa->setWidth(0x140 - _sequences[seqNum].xPos);
     150
     151                                if (_sequences[seqNum].yPos + _seqWsa->height() > 0xC7)
     152                                        _seqWsa->setHeight(0xC7 - _sequences[seqNum].yPos);
     153                        }
     154                        uint8 dir = (_sequences[seqNum].startFrame > _sequences[seqNum].numFrames) ? 0 : 1;
     155                        seqWsaCurrentFrame = _sequences[seqNum].startFrame;
     156
     157                        bool loop = true;
     158                        while (loop && !((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     159                                _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
     160
     161                                if (_seqWsa || !_sequences[seqNum].callback)
     162                                        _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
     163
     164                                if (_sequences[seqNum].callback) {
     165                                        int f = seqWsaCurrentFrame % _seqWsa->frames();
     166                                        (this->*_sequences[seqNum].callback)(_seqWsa, _sequences[seqNum].xPos, _sequences[seqNum].yPos, f);
     167                                }
     168
     169                                if (_seqWsa) {
     170                                        int f = seqWsaCurrentFrame % _seqWsa->frames();
     171                                        _seqWsa->setX(_sequences[seqNum].xPos);
     172                                        _seqWsa->setY(_sequences[seqNum].yPos);
     173                                        _seqWsa->setDrawPage(2);
     174                                        _seqWsa->displayFrame(f, 0);
     175                                }
     176
     177                                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     178
     179                                seq_processWSAs();             
     180                                seq_processText();
    106181                       
    107                         if (sequences[i].callback) {
    108                                 int newTime = (*this.*sequences[i].callback)(seqNum++);
    109                                 if (newTime != -1) {
    110                                         seqDelay = newTime * _tickLength + _system->getMillis();
    111                                         mayEndLoop = true;
     182                                if ((_seqWsa || !_sequences[seqNum].callback) && !((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     183                                        _screen->copyPage(2, 0);
     184                                        _screen->copyPage(2, 6);
     185                                        _screen->updateScreen();
    112186                                }
     187                               
     188                                bool loop2 = true;
     189                                while (loop2 && !((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     190                                        if (_seqWsa) {
     191                                                seq_processText();
     192                                                if (!((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     193                                                        _screen->copyPage(2, 0);
     194                                                        _screen->copyPage(2, 6);
     195                                                        _screen->updateScreen();
     196                                                }
     197
     198
     199                                                uint32 now = _system->getMillis();
     200                                                if (now >= _seqEndTime) {
     201                                                        loop2 = false;
     202                                                } else {
     203                                                        uint32 tdiff = _seqEndTime - now;
     204                                                        uint32 dly = tdiff < _tickLength ? tdiff : _tickLength;
     205                                                        delay(dly);
     206                                                        _seqEndTime -= dly;
     207                                                }
     208                                        } else {
     209                                                loop = loop2 = false;
     210                                        }
     211                                }
     212
     213                                if (loop) {
     214                                        if (dir == 1) {
     215                                                if (++seqWsaCurrentFrame >= _sequences[seqNum].numFrames)
     216                                                        loop = false;
     217                                        } else {
     218                                                if (--seqWsaCurrentFrame < _sequences[seqNum].numFrames)
     219                                                        loop = false;
     220                                        }
     221                                }
    113222                        }
     223                        _seqWsa->close();
     224
     225
     226                } else {
     227                        _seqFrameDelay = _sequences[seqNum].frameDelay;
     228                        _seqEndTime = _system->getMillis() + _seqFrameDelay * _tickLength;
     229                        while (!((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     230                                uint32 starttime = _system->getMillis();
     231                                seq_processWSAs();             
     232                                if (_sequences[seqNum].callback)
     233                                        (this->*_sequences[seqNum].callback)(0, 0, 0, 0);
     234                               
     235                                seq_processText();
     236       
     237                                _screen->copyPage(2, 6);               
     238                                _screen->copyPage(2, 0);
     239                                _screen->updateScreen();
     240                                _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
     241
     242                                uint32 now = _system->getMillis();
     243                                if (now >= _seqEndTime && !_seqSubframePlaying)
     244                                        break;
     245                               
     246                                uint32 tdiff = _seqEndTime - starttime;
     247                                int32 dly = _tickLength - (now - starttime);
     248                                if (dly > 0)
     249                                        delay(MIN<uint32>(dly, tdiff));
     250                        }
     251                }
     252
     253                if (_sequences[seqNum].callback)
     254                        (this->*_sequences[seqNum].callback)(0, 0, 0, -2);
     255
     256                uint32 ct = seq_activeTextsTimeLeft();
     257                uint32 dl = _sequences[seqNum].duration * _tickLength;
     258                if (dl < ct)
     259                        dl = ct;
     260                _seqEndTime = _system->getMillis() + dl;
    114261               
    115                         seq_playWSAs();
     262                while (!((_skipFlag && allowSkip) || _quitFlag || (_abortIntroFlag && allowSkip) || _menuChoice)) {
     263                        uint32 starttime = _system->getMillis();
     264                        seq_processWSAs();
     265
     266                        _screen->copyPage(2, 6);               
    116267                        _screen->copyPage(2, 0);
    117                         seq_showChats();
    118268                        _screen->updateScreen();
     269                        _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
    119270                       
    120                         uint32 currTime = _system->getMillis();
    121                         if (seqDelay <= currTime && mayEndLoop) {
     271                        uint32 now = _system->getMillis();
     272                        if (now >= _seqEndTime && !_seqSubframePlaying) {
    122273                                break;
    123274                        } else {
    124                                 uint32 loopTime = currTime - startTime;
    125                                 delay(loopTime < _tickLength ? loopTime : _tickLength);
     275                                uint32 tdiff = _seqEndTime - starttime;
     276                                delay(MIN<uint32>(tdiff, _tickLength));
    126277                        }
    127278                }
     279               
     280                seq_sequenceCommand(_sequences[seqNum].finalCommand);
     281                seq_resetAllTextEntries();
    128282
    129                 if (sequences[i].fadeOut)
    130                         _screen->fadeToBlack(40);
     283                if ((seqNum != kSequenceTitle && seqNum < kSequenceZanfaun &&
     284                        (_abortIntroFlag || _skipFlag)) || seqNum == kSequenceZanfaun) {
     285                        _abortIntroFlag = _skipFlag = false;
     286                        seqNum = kSequenceWestwood;
     287                }
    131288               
    132                 if (sequences[i].type == 1)
    133                         seq_unloadWSA(0);
    134                
    135                 _screen->clearPage(2);
    136                
     289                if (_menuChoice) {
     290                        _abortIntroFlag = _skipFlag = false;
     291                        if (_menuChoice == 2)
     292                                _menuChoice = 0;
     293                }
    137294        }
     295
    138296        _screen->setCurPage(oldPage);
    139297        _screen->showMouse();
    140298
    141299        for (int i = 0; i < 8; i++)
    142300                seq_unloadWSA(i);
    143         delete[] _activeWSA;
    144         delete[] _activeChat;
     301
     302        if (_seqWsa->opened())
     303                _seqWsa->close();
     304
     305        _screen->_charWidth = 0;
     306
     307        seq_uninit();
    145308}
    146309
    147 // FIXME: This part needs game dialogs, as it's not part of the intro, but
    148 // rather a game video. It has speech only in the CD version
    149 int KyraEngine_v2::seq_introZanFaun(int seqNum) {
    150         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introZanFaun(%i)", seqNum);
     310int KyraEngine_v2::seq_introWestwood(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     311        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introWestwood(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm);
     312       
     313        if (frm == -2)
     314                delay(0x12C * _tickLength);
     315        else if (!frm)
     316                _sound->playTrack(2);
     317       
     318        return 0;
     319}
    151320
    152         static const SequenceControl zanFaunWSAControl[] = {
    153                 {0, 6}, {1, 6}, {2, 6}, {3, 6},
    154                 {4, 6}, {5, 6}, {6, 6}, {7, 6},
    155                 {8, 6}, {9, 6}, {10, 6}, {11, 6},
    156                 {12, 6}, {13, 6}, {14, 6}, {15, 6},
    157                 {16, 6}, {17, 6}, {18, 6}, {19, 6},
    158                 {20, 6}, {21, 6}, {22, 6}, {23, 6},
    159                 {23, 6}, {22, 6}, {21, 6}, {20, 6},
    160                 {19, 6}, {18, 6}, {17, 6}, {16, 6},
    161                 {15, 6}, {14, 6}, {13, 6}, {12, 6},
    162                 {11, 6}, {10, 6}, {9, 6}, {8, 6},
    163                 {7, 6}, {6, 6}, {5, 6}, {4, 6},
    164                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    165                 {8, 6}, {9, 6}, {10, 6}, {-1, -1} };
     321int KyraEngine_v2::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     322        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introTitle(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm);
     323       
     324        if (frm == 1) {
     325                _sound->playTrack(3);
     326        } else if (frm == 0x19) {
     327                int cp = _screen->setCurPage(0);
     328                _screen->showMouse();
     329                _system->updateScreen();
     330                _menuChoice = gui_handleMainMenu() + 1;
     331                _seqEndTime = 0;
     332                _seqSubframePlaying = false;
     333                if (_menuChoice == 4)
     334                        quitGame();
    166335
    167         switch (seqNum) {
    168                 case 0:
    169                         _sound->playTrack(8);
    170                         //XXX: palette stuff
    171                         //XXX: load dialogs
    172                         break;
    173                 case 1:
    174                         seq_loadWSA(1, "zanfaun.wsa", 9, 0, zanFaunWSAControl);
    175                         break;
    176                 case 0x294:
    177                         seq_waitForChatsToFinish();
    178                         seq_unloadWSA(1);
    179                         return 0;
    180                 default:
    181                         break;
     336                _screen->hideMouse();
     337                _screen->setCurPage(cp);
    182338        }
    183339
    184         return -1;
     340        return 0;
    185341}
    186342
    187 int KyraEngine_v2::seq_introPoint(int seqNum) {
    188         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introPoint(%i)", seqNum);
     343int KyraEngine_v2::seq_introOverview(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     344        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverview(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm);
     345       
     346        uint8 * tmpPal = &(_screen->getPalette(3)[0x101]);
     347        memset(tmpPal, 0, 0x100);
     348        uint8 txtColorMap[0x10];
     349        uint32 endtime = 0, now = 0;
    189350
    190         switch (seqNum) {
    191                 case 0:
    192                         _sound->playTrack(7);
    193                         break;
    194                 case 1:
    195                         seq_loadWSA(1, "point.wsa", 9);
    196                         seq_playIntroChat(11); // "Zanthia, youngest of the royal mystics has been selected"
    197                         break;
    198                 case 0x96:
    199                         seq_waitForChatsToFinish();
    200                         seq_unloadWSA(1);
    201                         return 0;
    202                 default:
    203                         break;
     351        switch (_seqFrameCounter) {
     352        case 0:
     353                _seqSubframePlaying = true;
     354                _sound->playTrack(4);
     355                endtime = _system->getMillis() + 0x3c * _tickLength;
     356                       
     357                _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
     358                memset(txtColorMap, _seqTextColor[1], 16);
     359                txtColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
     360
     361                _screen->setTextColorMap(txtColorMap);
     362               
     363                now = _system->getMillis();
     364                if (endtime > now)
     365                        delay(endtime - now);
     366                break;
     367
     368        case 1:
     369                _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x40, 0, 0, 0, 0x100, true);
     370                for (int i = 0; i < 0x100; i++)
     371                        tmpPal[_screen->getPalette(3)[i]] = 1;
     372
     373                for (int i = 0; i < 0x100; i++) {
     374                        int v = (tmpPal[i] == 1) ? i : _screen->getPalette(3)[i];
     375                        v *= 3;
     376                        _screen->getPalette(2)[3 * i] = _screen->getPalette(0)[v];
     377                        _screen->getPalette(2)[3 * i + 1] = _screen->getPalette(0)[v + 1];
     378                        _screen->getPalette(2)[3 * i + 2] = _screen->getPalette(0)[v + 2];
     379                }
     380                break;
     381
     382        case 0x28:
     383                seq_loadNestedSequence(0, kSequenceOver1);
     384                break;
     385
     386        case 0x3C:
     387                seq_loadNestedSequence(1, kSequenceOver2);
     388                break;
     389
     390        case 0x78:
     391                seq_playTalkText(0);
     392                break;
     393
     394        case 0xc8:
     395                seq_waitForTextsTimeout();
     396                _screen->fadePalette(_screen->getPalette(2), 0x40);
     397                break;
     398
     399        case 0xc9:
     400                _screen->setScreenPalette(_screen->getPalette(2));
     401                _screen->updateScreen();
     402                _screen->applyGrayOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
     403                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     404                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
     405                _screen->setScreenPalette(_screen->getPalette(0));
     406                _screen->updateScreen();
     407                seq_resetActiveWSA(0);
     408                seq_resetActiveWSA(1);
     409                break;
     410
     411        case 0x11a:
     412                seq_loadNestedSequence(0, kSequenceForest);
     413                seq_playTalkText(1);
     414                break;
     415
     416        case 0x162:
     417                seq_resetActiveWSA(0);
     418                seq_loadNestedSequence(0, kSequenceDragon);
     419                break;
     420
     421        case 0x190:
     422                seq_waitForTextsTimeout();
     423                seq_resetActiveWSA(0);
     424                _seqEndTime = 0;
     425                _seqSubframePlaying = false;
     426                break;
     427
     428        default:
     429                break;
    204430        }
    205431
    206         return -1;
     432        _seqFrameCounter++;
     433        return 0;
    207434}
    208435
    209 int KyraEngine_v2::seq_introHand(int seqNum) {
    210         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introHand(%i)", seqNum);
    211         // XXX: commented out to prevent compiler warnings
    212         /*static const SequenceControl hand1bWSAControl[] = {
    213                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {5, 6}, {6, 6}, {7, 6},
    214                 {8, 6}, {9, 6}, {10, 6}, {11, 6}, {11, 12}, {12, 12}, {13, 12},
    215                 {12, 12}, {11, 12}, {-1, -1} };
    216        
    217         static const SequenceControl hand1cWSAControl[] = {
    218                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6}, {3, 6},
    219                 {4, 6}, {5, 64}, {5, 6}, {-1, -1} };*/
    220        
    221         static const SequenceControl hand2WSAControl[] = {
    222                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    223                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    224                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    225                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    226                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    227                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    228                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    229                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    230                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    231                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    232                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6},
    233                 {0, 6}, {1, 6}, {0, 6}, {1, 6}, {0, 6}, {1, 6}, {-1, -1} };
     436int KyraEngine_v2::seq_introLibrary(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     437        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introLibrary(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm);
     438        uint8 txtColorMap[0x10];
    234439
    235         static const SequenceControl hand3WSAControl[] = {
    236                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    237                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    238                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    239                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    240                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    241                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    242                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    243                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    244                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    245                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    246                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    247                 {0, 6}, {1, 6}, {2, 6}, {1, 6},
    248                 {0, 6}, {-1, -1} };
     440        switch (_seqFrameCounter) {
     441        case 0:
     442                _seqSubframePlaying = true;
     443                _sound->playTrack(5);
     444                       
     445                _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
     446                _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
     447                memset(txtColorMap, _seqTextColor[1], 16);
     448                txtColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
    249449
    250         static const SequenceControl hand4WSAControl[] = {
    251                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    252                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    253                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    254                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    255                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    256                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    257                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    258                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    259                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    260                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    261                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    262                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    263                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    264                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    265                 {0, 6}, {1, 6}, {2, 6}, {3, 6}, {4, 6},
    266                 {3, 6}, {2, 6}, {1, 6}, {0, 6},
    267                 {-1, -1} };
    268        
    269         switch (seqNum) {
    270                 case 0:
    271                         _sound->playTrack(6);
    272                         //palette stuff
    273                         break;
    274                 case 1:
    275                         // XXX: these show as garbage. New frame encode?
    276                         /*seq_loadWSA(1, "hand1a.wsa", 9);
    277                         seq_loadWSA(2, "hand1b.wsa", 9, 0, hand1bWSAControl);
    278                         seq_loadWSA(3, "hand1c.wsa", 9, 0, hand1cWSAControl);*/
    279                         seq_playIntroChat(7); // "Luckily, the Hand was experienced in these matters"
    280                         break;
    281                 case 0xc9:
    282                         // palette stuff
    283                         seq_loadWSA(4, "hand2.wsa", 9, 0, hand2WSAControl);
    284                         seq_waitForChatsToFinish();
    285                         seq_playIntroChat(8); // "and finally, a plan was approved"
    286                         break;
    287                 case 0x18b:
    288                         seq_loadWSA(5, "hand3.wsa", 9, 0, hand3WSAControl);
    289                         seq_waitForChatsToFinish();
    290                         seq_playIntroChat(9); // "which required a magic anchorstone"
    291                         break;
    292                 case 0x1f4:
    293                         seq_loadWSA(6, "hand4.wsa", 9, 0, hand4WSAControl);
    294                         seq_waitForChatsToFinish();
    295                         seq_playIntroChat(10); // "to be retrieved from the center of the world"
    296                         break;
    297                 case 0x320:
    298                         seq_waitForChatsToFinish();
    299                         /*seq_unloadWSA(1);
    300                         seq_unloadWSA(2);       
    301                         seq_unloadWSA(3);*/
    302                         seq_unloadWSA(4);
    303                         seq_unloadWSA(5);
    304                         seq_unloadWSA(6);                                               
    305                         return 0;
     450                _screen->setTextColorMap(txtColorMap);
     451                break;
     452
     453        case 1:
     454                seq_loadNestedSequence(0, kSequenceLibrary3);
     455                seq_playTalkText(4);
     456                break;
     457
     458        case 0x64:
     459                seq_waitForTextsTimeout();
     460
     461                _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
     462                _screen->applyGrayOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
     463                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
     464                _screen->updateScreen();
     465                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     466                       
     467                seq_resetActiveWSA(0);
     468                seq_loadNestedSequence(0, kSequenceDarm);
     469
     470                break;
     471
     472        case 0x68:
     473                seq_playTalkText(5);
     474                break;
     475
     476        case 0xf0:
     477                seq_waitForTextsTimeout();
     478                seq_resetActiveWSA(0);
     479                seq_loadNestedSequence(0, kSequenceLibrary2);
     480                break;
     481
     482        case 0x154:
     483                seq_resetActiveWSA(0);
     484                _screen->applyGrayOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
     485                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     486                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
     487                _screen->updateScreen();
     488
     489                seq_loadNestedSequence(0, kSequenceMarco);
     490                seq_playTalkText(6);
     491                break;
     492
     493        case 0x1e0:
     494                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     495                seq_waitForTextsTimeout();
     496                seq_resetActiveWSA(0);
     497                _seqEndTime = 0;
     498                _seqSubframePlaying = false;
     499                break;
     500
     501        default:
     502                break;
    306503        }
    307        
    308         return -1;
     504
     505        _seqFrameCounter++;
     506        return 0;
    309507}
    310508
    311 int KyraEngine_v2::seq_introLibrary(int seqNum) {
    312         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introLibrary(%i)", seqNum);
    313        
    314         static const SequenceControl libraryWSAControl[] = {
    315                 {0, 10}, {1, 10}, {2, 10}, {3, 10}, {4, 10}, {5, 10}, {6, 10}, {7, 10},
    316                 {8, 10}, {9, 10}, {8, 10}, {7, 10}, {6, 10}, {5, 40}, {4, 10}, {3, 10},
    317                 {2, 10}, {1, 10}, {-1, -1} };
    318        
    319         switch (seqNum) {
    320                 case 0:
    321                         _sound->playTrack(5);
    322                         seq_playIntroChat(4); // "The royal mystics are baffled"
    323                         //XXX: palette stuff
    324                         break;
    325                 case 1:
    326                         seq_loadWSA(1, "library.wsa", 9, 0, libraryWSAControl);
    327                         break;
    328                 case 0x64:
    329                         seq_waitForChatsToFinish();
    330                         // unk1 = 7;
    331                         // palette/screen stuff
    332                         seq_loadWSA(2, "darm.wsa", 9);
    333                         break;
    334                 case 0x68:
    335                         seq_waitForChatsToFinish();
    336                         seq_playIntroChat(5);  // "Every reference has been consulted"
    337                         break;
    338                 case 0xF0:
    339                         seq_waitForChatsToFinish();
    340                         seq_loadWSA(3, "library.wsa", 9);
    341                         break;
    342                 case 0x154:
    343                         seq_waitForChatsToFinish();
    344                         // palette stuff
    345                         seq_loadWSA(4, "marco.wsa", 9);
    346                         seq_playIntroChat(6); // "Even Marko and his new valet have been allowed"
    347                         break;
    348                 case 0x294:
    349                         seq_waitForChatsToFinish();
    350                         seq_unloadWSA(1);
    351                         seq_unloadWSA(2);
    352                         seq_unloadWSA(3);
    353                         seq_unloadWSA(4);
    354                         return 0;
    355                 default:
    356                         break;
     509
     510int KyraEngine_v2::seq_introHand(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     511        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introHand(%p, %i, %i, %i)", (const void*)wsaObj, x, y, frm);
     512        uint8 txtColorMap[0x10];
     513        switch (_seqFrameCounter) {
     514        case 0:
     515                _seqSubframePlaying = true;
     516                _sound->playTrack(6);
     517                       
     518                _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
     519                _seqTextColor[1] = _screen->findLeastDifferentColor(_seqTextColorPresets, _screen->getPalette(0) + 3, 255) & 0xff;
     520                memset(txtColorMap, _seqTextColor[1], 16);
     521                txtColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
     522
     523                _screen->setTextColorMap(txtColorMap);
     524                break;
     525
     526        case 1:
     527                seq_loadNestedSequence(0, kSequenceHand1a);
     528                seq_loadNestedSequence(1, kSequenceHand1b);
     529                seq_loadNestedSequence(2, kSequenceHand1c);
     530                seq_playTalkText(7);
     531                break;
     532
     533        case 0xc9:
     534                seq_waitForTextsTimeout();
     535                _screen->applyGrayOverlay(0, 0, 320, 200, 2, _screen->getPalette(3));
     536                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     537                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
     538                _screen->updateScreen();
     539                seq_resetActiveWSA(0);
     540                seq_resetActiveWSA(1);
     541                seq_resetActiveWSA(2);
     542                seq_loadNestedSequence(0, kSequenceHand2);
     543                seq_playTalkText(8);
     544                break;
     545
     546        case 0x104:
     547                seq_waitForTextsTimeout();
     548                seq_resetActiveWSA(0);
     549                seq_loadNestedSequence(1, kSequenceHand3);
     550                seq_playTalkText(9);
     551                break;
     552
     553        case 0x16d:
     554                seq_waitForTextsTimeout();
     555                seq_resetActiveWSA(1);
     556                seq_loadNestedSequence(0, kSequenceHand4);
     557                break;
     558
     559        case 0x195:
     560                seq_playTalkText(10);
     561                break;
     562
     563        case 0x1E4:
     564                seq_waitForTextsTimeout();
     565                seq_resetActiveWSA(0);
     566                _seqEndTime = 0;
     567                _seqSubframePlaying = false;
     568                break;
     569
     570        default:
     571                break;
    357572        }
    358573
    359         return -1;
     574        _seqFrameCounter++;
     575        return 0;
    360576}
    361577
    362 int KyraEngine_v2::seq_introOverview(int seqNum) {
    363         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverview(%i)", seqNum);
    364        
    365         switch (seqNum) {
    366                 case 0:
    367                         _sound->playTrack(4);
    368                         break;
    369                 case 40:
    370                         seq_loadWSA(1, "over1.wsa", 10, &KyraEngine_v2::seq_introOverviewOver1);
    371                         break;
    372                 case 60:
    373                         seq_loadWSA(2, "over2.wsa", 9);
    374                         break;
    375                 case 120:
    376                         seq_playIntroChat(0); // "Kyrandia is disappearing!"
    377                         break;
    378                 case 200:
    379                         seq_waitForChatsToFinish();
    380                         // XXX: fade to grey
    381                         _screen->k2IntroFadeToGrey(40);
    382                         break;
    383                 case 201:
    384                         // XXX
    385                         break;
    386                 case 282:
    387                         seq_waitForChatsToFinish();
    388                         seq_loadWSA(3, "forest.wsa", 6,  &KyraEngine_v2::seq_introOverviewForest);
    389                         seq_playIntroChat(1); // "Rock by rock..."
    390                         break;
    391                 case 434:
    392                         seq_waitForChatsToFinish();
    393                         seq_loadWSA(4, "dragon.wsa", 6,  &KyraEngine_v2::seq_introOverviewDragon);
    394                         break;
    395                 case 540:
    396                         seq_waitForChatsToFinish();
    397                         seq_unloadWSA(1);
    398                         seq_unloadWSA(2);
    399                         seq_unloadWSA(3);
    400                         seq_unloadWSA(4);
    401                         return 0;
    402                         break; 
     578int KyraEngine_v2::seq_introPoint(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     579        if (frm == -2) {
     580                seq_waitForTextsTimeout();
     581                _seqEndTime = 0;
    403582        }
    404583
    405         return -1;
     584        uint8 txtColorMap[0x10];
     585
     586        switch (_seqFrameCounter) {
     587        case -2:
     588                seq_waitForTextsTimeout();
     589                break;
     590
     591        case 0:
     592                _sound->playTrack(7);                   
     593                       
     594                _seqTextColor[1] = 0xf7;
     595                memset(txtColorMap, _seqTextColor[1], 16);
     596                txtColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
     597                _screen->setTextColorMap(txtColorMap);
     598                _screen->generateGrayOverlay(_screen->getPalette(0), _screen->getPalette(3), 0x24, 0, 0, 0, 0x100, false);
     599                break;
     600
     601        case 1:
     602                seq_playTalkText(11);
     603                break;
     604
     605        default:
     606                break;
     607        }
     608
     609        _seqFrameCounter++;
     610        return 0;
    406611}
    407612
    408 void KyraEngine_v2::seq_introOverviewOver1(int currentFrame) {
    409         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverviewOver1(%i)", currentFrame);
     613int KyraEngine_v2::seq_introZanfaun(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     614        if (frm == -2) {
     615                seq_waitForTextsTimeout();
     616                _seqEndTime = 0;
     617                return 0;
     618        }
     619
     620        uint8 txtColorMap[0x10];
     621
     622        switch (_seqFrameCounter) {
     623        case 0:
     624                _sound->playTrack(8);                   
     625                       
     626                _seqTextColor[1] = 0xfd;
     627                memset(txtColorMap, _seqTextColor[1], 16);
     628                txtColorMap[1] = _seqTextColor[0] = _screen->findLeastDifferentColor(_seqTextColorPresets + 3, _screen->getPalette(0) + 3, 255) & 0xff;
     629                _screen->setTextColorMap(txtColorMap);
     630                break;
     631
     632        case 1:
     633                seq_setTextEntry(0x15, 0x8c, 0x46, 0xc8, 0xa0);
     634                if (_flags.isTalkie)
     635                        _sound->voicePlay(_sequenceSoundList[0x0D]);
     636                _seqFrameDelay = 0xc8;
     637                break;
     638
     639        case 2:
     640        case 11:
     641        case 21:
     642                _seqFrameDelay = 0x0c;
     643                break;
     644
     645        case 10:
     646                seq_waitForTextsTimeout();
     647                seq_setTextEntry(0x0D, 0x8c, 0x32, _sequenceStringsDuration[13], 0xa0);
     648                if (_flags.isTalkie)
     649                        _sound->voicePlay(_sequenceSoundList[0x0E]);
     650                _seqFrameDelay = 0x12C;
     651                break;
     652
     653        case 20:
     654                seq_setTextEntry(0x12, 0xa0, 0x32, _sequenceStringsDuration[17], 0xa0);
     655                if (_flags.isTalkie)
     656                        _sound->voicePlay(_sequenceSoundList[0x0F]);
     657                _seqFrameDelay = 0xc8;
     658                break;
     659
     660        case 19:
     661        case 26:
     662                seq_waitForTextsTimeout();
     663                break;
     664
     665        case 0x2E:
     666                seq_waitForTextsTimeout();
     667                seq_setTextEntry(0x10, 0xc8, 0x32, _sequenceStringsDuration[16], 0x78);
     668                if (_flags.isTalkie)
     669                        _sound->voicePlay(_sequenceSoundList[0x10]);
     670                _seqEndTime = _system->getMillis() + 0x78 * _tickLength;
     671                break;
     672
     673        default:
     674                break;
     675        }       
    410676       
    411         if (currentFrame == 2)
    412                 seq_waitForChatsToFinish();
    413         else if (currentFrame == 3)
    414                 seq_playIntroChat(12);
     677        _seqFrameCounter++;
     678        return 0;
    415679}
    416680
    417 void KyraEngine_v2::seq_introOverviewForest(int currentFrame) {
    418         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverviewForest(%i)", currentFrame);
    419        
    420         if (currentFrame == 11) {
    421                 seq_waitForChatsToFinish();
    422         } else if (currentFrame == 12) {
    423                 delay(25);
    424                 seq_playIntroChat(2); // "...and tree by tree..."
     681int KyraEngine_v2::seq_introOver1(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     682        if (frm == 2)
     683                seq_waitForTextsTimeout();
     684        else if (frm == 3)
     685                seq_playTalkText(12);
     686        return frm;
     687}
     688
     689
     690int KyraEngine_v2::seq_introOver2(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     691        if (frm == 1)
     692                seq_playTalkText(12);
     693        return frm;
     694}
     695
     696int KyraEngine_v2::seq_introForest(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     697        if (frm == 11)
     698                seq_waitForTextsTimeout();
     699        else if (frm == 12)
     700                seq_playTalkText(2);
     701        return frm;
     702}
     703
     704int KyraEngine_v2::seq_introDragon(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     705        if (frm == 11)
     706                seq_waitForTextsTimeout();
     707        else if (frm == 3)
     708                seq_playTalkText(3);
     709        return frm;
     710}
     711
     712int KyraEngine_v2::seq_introDarm(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     713        //NULLSUB (at least in fm-towns version)
     714        return frm;
     715}
     716
     717int KyraEngine_v2::seq_introLibrary2(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     718        //NULLSUB (at least in fm-towns version)
     719        return frm;
     720}
     721
     722int KyraEngine_v2::seq_introMarco(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     723        if (frm == 0x24) {
     724                seq_waitForTextsTimeout();
     725                _seqEndTime = 0;
    425726        }
     727        return frm;
    426728}
    427729
    428 void KyraEngine_v2::seq_introOverviewDragon(int currentFrame) {
    429         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introOverviewDragon(%i)", currentFrame);
    430        
    431         if (currentFrame == 3)
    432                 seq_playIntroChat(3); // "Kyrandia ceases to exist!"
    433         else if (currentFrame == 11)
    434                 seq_waitForChatsToFinish();
     730int KyraEngine_v2::seq_introHand1a(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     731        //NULLSUB (at least in fm-towns version)
     732        return frm;
    435733}
    436734
    437 int KyraEngine_v2::seq_introTitle(int seqNum) {
    438         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introtitle(%i)", seqNum);
    439        
    440         if (seqNum == 1) {
    441                 _sound->playTrack(3);
    442         } else if (seqNum == 25) {
    443                 // XXX: handle menu
    444                 return 200;
     735int KyraEngine_v2::seq_introHand1b(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     736        if (frm == 15)
     737                frm = 12;
     738        return frm;
     739}
     740
     741int KyraEngine_v2::seq_introHand1c(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     742        if (frm == 8)
     743                frm = 4;
     744        return frm;
     745}
     746
     747int KyraEngine_v2::seq_introHand2(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     748        //NULLSUB (at least in fm-towns version)
     749        return frm;
     750}
     751
     752int KyraEngine_v2::seq_introHand3(WSAMovieV2 *wsaObj, int x, int y, int frm) {
     753        //NULLSUB (at least in fm-towns version)
     754        return frm;
     755}
     756
     757uint32 KyraEngine_v2::seq_activeTextsTimeLeft() {
     758        uint32 res = 0;
     759
     760        for (int i = 0; i < 10; i++) {
     761                uint32 chatend = (_activeText[i].duration + _activeText[i].startTime);
     762                uint32 curtime = _system->getMillis();
     763                if (_activeText[i].duration != -1 && chatend > curtime) {
     764                        chatend -= curtime;
     765                        if (res < chatend)
     766                                res = chatend;
     767                }
    445768        }
    446769
    447         return -1;
     770        return res;
    448771}
    449772
    450 int KyraEngine_v2::seq_introWestwood(int seqNum) {
    451         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_introWestwood(%i)", seqNum);
    452        
    453         if (seqNum == 0)
    454                 _sound->playTrack(2);
     773void KyraEngine_v2::seq_processWSAs() {
     774        for (int i = 0; i <  8; i++) {
     775                if (_activeWSA[i].flags != -1) {
     776                        if(seq_processNextSubFrame(i))
     777                                seq_resetActiveWSA(i);
     778                }
     779        }
     780}
    455781
    456         return -1;
     782void KyraEngine_v2::seq_processText() {
     783        Screen::FontId cfid = _screen->setFont(Screen::FID_GOLDFONT_FNT);
     784        int cp = _screen->setCurPage(2);
     785        char s2[60];
     786
     787        for (int i = 0; i < 10; i++) {
     788                if (_activeText[i].startTime + _activeText[i].duration > _system->getMillis() && _activeText[i].duration != -1) {
     789
     790                        char * s = seq_preprocessString(_sequenceStrings[_activeText[i].strIndex], _activeText[i].width);
     791                        int cy = _activeText[i].y;
     792
     793                        while (*s) {
     794                                uint32 t = 0;
     795                                for (; *s; t++) {
     796                                        if (*s == 0x0d)
     797                                                break;
     798                                        s2[t] = *s;
     799                                        s++;
     800                                }
     801                s2[t] = 0;
     802                                if (*s == 0x0d)
     803                                        s++;
     804
     805                                uint8 tcol = (_activeText[i].textcolor + 1) ? _activeText[i].textcolor : _seqTextColor[0];
     806                                _screen->printText(s2, _activeText[i].x - (_screen->getTextWidth(s2) >> 1), cy, tcol, 0);
     807                                cy += 0x0a;
     808                        }
     809                } else {
     810                        _activeText[i].duration = -1;
     811                }
     812        }
     813
     814        _screen->setCurPage(cp);
     815        _screen->setFont(cfid);
    457816}
    458817
    459 void KyraEngine_v2::seq_playIntroChat(uint8 chatNum) {
    460         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playIntroChat(%i)", chatNum);
     818char *KyraEngine_v2::seq_preprocessString(const char *s, int width) {
     819        char *d = _seqProcessedString;
     820        int b = 0;
     821        int i = 0;
    461822       
    462         assert(chatNum < _introSoundListSize);
     823        while (*s) {
     824                while (*s && *s != 0x20)
     825                        d[b + i++] = *s++;
     826                d[b + i] = 0;
     827
     828                int len = _screen->getTextWidth(&d[b]);
     829                if (width >= len && *s) {
     830                        d[b + i++] = *s++;                     
     831                } else {
     832                        d[b + i] = 0x0d;
     833                        b = (b + 1) + i;
     834                        i = 0;
     835                        if (*s)
     836                                s++;
     837                }
     838        }
     839        d[b + i] = 0;
    463840       
    464         if (chatNum < 12)
    465                 seq_setChatEntry(chatNum, 160, 168, _introStringsDuration[chatNum], 160);
    466         _sound->voicePlay(_introSoundList[chatNum]);
     841        return strlen(_seqProcessedString) ? d : 0;
    467842}
    468843
    469 void KyraEngine_v2::seq_waitForChatsToFinish() {
    470         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_waitForChatsToFinish()");
     844void KyraEngine_v2::seq_sequenceCommand(int command) {
     845        uint8 pal[768];
     846   
     847        for (int i = 0; i < 8; i++)
     848                seq_resetActiveWSA(i);
    471849       
    472         uint32 longest = 0;
     850        switch (command) {
     851        case 0:
     852                memset(pal, 0, 0x300);
     853                _screen->fadePalette(pal, 0x10);
     854                memcpy (_screen->getPalette(0), pal, 0x300);
     855                memcpy (_screen->getPalette(1), pal, 0x300);
     856                break;
     857
     858        case 1:
     859                memset(pal, 0x3F, 0x300);
     860                //////////TODO
     861                //////////Unused anyway (at least by fm-towns intro/outro)
     862
     863                _screen->fadePalette(pal, 0x10);
     864                memcpy (_screen->getPalette(0), pal, 0x300);
     865                memcpy (_screen->getPalette(1), pal, 0x300);
     866                break;
     867
     868        case 3:
     869                _screen->copyPage(2, 0);
     870                _screen->fadePalette(_screen->getPalette(0), 0x10);
     871                memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300);
     872                break;
     873
     874        case 4:
     875                _screen->copyPage(2, 0);
     876                _screen->fadePalette(_screen->getPalette(0), 0x24);
     877                memcpy (_screen->getPalette(1), _screen->getPalette(0), 0x300);
     878                break;
     879
     880        case 5:
     881                _screen->copyPage(2, 0);
     882                break;
    473883       
    474         for (int i = 0; i < 10; i++) {
    475                 if (_activeChat[i].duration != -1) {
    476                         uint32 currChatTime = _activeChat[i].duration + _activeChat[i].startTime;
    477                         if ( currChatTime > longest)
    478                                 longest = currChatTime;
     884        case 6:
     885                // UNUSED
     886                // seq_loadBLD("library.bld");
     887                break;
     888
     889        case 7:
     890                // UNUSED
     891                // seq_loadBLD("marco.bld");
     892                break;
     893       
     894        case 8:
     895                memset(pal, 0, 0x300);
     896                _screen->fadePalette(pal, 0x10);
     897                memcpy (_screen->getPalette(0), pal, 0x300);
     898                memcpy (_screen->getPalette(1), pal, 0x300);
     899
     900                delay(0x78 * _tickLength);
     901                break;
     902       
     903        case 9:
     904                for (int i = 0; i < 0x100; i++) {
     905                        int pv = (_screen->getPalette(0)[3 * i] + _screen->getPalette(0)[3 * i + 1] + _screen->getPalette(0)[3 * i + 2]) / 3;
     906                        pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = pv & 0xff;
    479907                }
     908
     909                //int a = 0x100;
     910                //int d = (0x800 << 5) - 0x100;
     911                //pal[3 * i] = pal[3 * i + 1] = pal[3 * i + 2] = 0x3f;
     912
     913                _screen->fadePalette(pal, 0x40);
     914                memcpy (_screen->getPalette(0), pal, 0x300);
     915                memcpy (_screen->getPalette(1), pal, 0x300);
     916                break;
     917
     918        default:
     919                break;
    480920        }
     921}
    481922
     923void KyraEngine_v2::seq_cmpFadeFrame(const char * cmpFile) {
     924        _screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer1);
     925        _screen->copyRegionToBuffer(4, 0, 0, 320, 200, _pageBuffer1);
     926        _screen->clearPage(6);
     927        _screen->loadBitmap(cmpFile, 6, 6, 0);
     928        _screen->copyBlockToPage(4, 0, 0, 320, 200, _pageBuffer2);
     929
     930        for (int i = 0; i < 3; i++) {
     931                uint32 endtime = _system->getMillis() + 4 * _tickLength;
     932                _screen->cmpFadeFrameStep(4, 320, 200, 0, 0, 2, 320, 200, 0, 0, 320, 200, 6);
     933                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0);
     934                _screen->updateScreen();
     935        delayUntil(endtime);
     936        }
     937
     938        _screen->copyPage(4, 0);
     939        _screen->updateScreen();
     940        _screen->copyPage(4, 2);
     941        _screen->copyPage(4, 6);
     942        _screen->copyBlockToPage(4, 0, 0, 320, 200, _pageBuffer1);
     943}
     944
     945void KyraEngine_v2::seq_playTalkText(uint8 chatNum) {
     946        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playIntroChat(%i)", chatNum);
     947       
     948        assert(chatNum < _sequenceSoundListSize);
     949
     950        if (chatNum < 12)
     951                seq_setTextEntry(chatNum, 160, 168, _sequenceStringsDuration[chatNum], 160);
     952
     953        _sound->voicePlay(_sequenceSoundList[chatNum]);
     954}
     955
     956void KyraEngine_v2::seq_waitForTextsTimeout() {
     957        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_waitForTextsTimeout()");
     958       
     959        uint32 longest = seq_activeTextsTimeLeft() + _system->getMillis();
    482960        uint32 now = _system->getMillis();
    483961        if (longest > now)
    484962                delay(longest - now);
     963
     964        seq_resetAllTextEntries();
    485965}
    486966
    487 void KyraEngine_v2::seq_resetAllChatEntries() {
    488         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_resetAllChatEntries()");
    489        
    490         for (int i = 0; i < 10; i++)
    491                 _activeChat[i].duration = -1;
     967void KyraEngine_v2::seq_resetAllTextEntries() {
     968        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_resetAllTextEntries()");
     969        for (int i = 0; i < 10; ++i)
     970                _activeText[i].duration = -1;
    492971}
    493972
    494 void KyraEngine_v2::seq_setChatEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 unk1) {
    495         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_setChatEntry(%i, %i, %i, %i, %i)", strIndex, posX, posY, duration, unk1);
     973int KyraEngine_v2::seq_setTextEntry(uint16 strIndex, uint16 posX, uint16 posY, int duration, uint16 width) {
     974        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_setTextEntry(%i, %i, %i, %i, %i)", strIndex, posX, posY, duration, width);
    496975       
    497976        for (int i = 0; i < 10; i++) {
    498                 if (_activeChat[i].duration != -1)
    499                         continue;
     977                if (_activeText[i].duration != -1) {
     978                        if (i < 9)
     979                                continue;
     980                        else
     981                                return -1;
     982                }
    500983
    501                 _activeChat[i].strIndex = strIndex;
    502                 _activeChat[i].x = posX;
    503                 _activeChat[i].y = posY;
    504                 _activeChat[i].duration = duration * _tickLength;
    505                 _activeChat[i].field_8 = unk1;
    506                 _activeChat[i].startTime = _system->getMillis();
     984                _activeText[i].strIndex = strIndex;
     985                _activeText[i].x = posX;
     986                _activeText[i].y = posY;
     987                _activeText[i].duration = duration * _tickLength;
     988                _activeText[i].width = width;
     989                _activeText[i].startTime = _system->getMillis();
     990                _activeText[i].textcolor = -1;         
    507991
    508                 return;
     992                return i;
    509993        }
     994        return -1;
    510995}
    511996
    512 void KyraEngine_v2::seq_showChats() {
    513         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_showChats()");
     997void KyraEngine_v2::seq_loadNestedSequence(int wsaNum, int seqNum) {
     998        debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_loadNestedSequence(%i, %i)", wsaNum, seqNum);
     999
     1000        if (_activeWSA[wsaNum].flags != -1)
     1001                return;
    5141002       
    515         uint32 now = _system->getMillis();
     1003        NestedSequence s = _nSequences[seqNum];
     1004       
     1005        if (!_activeWSA[wsaNum].movie) {
     1006                _activeWSA[wsaNum].movie = new WSAMovieV2(this);       
     1007                assert(_activeWSA[wsaNum].movie);
     1008        }
    5161009
    517         for (int i = 0; i < 10; i++) {
    518                 if (_activeChat[i].duration != -1) {
    519                         if ((_activeChat[i].startTime + (uint32)_activeChat[i].duration) > now) {
    520                                 assert(_activeChat[i].strIndex < _introStringsSize);
    521                                
    522                                 _text->printIntroTextMessage(_introStrings[_activeChat[i].strIndex], _activeChat[i].x, _activeChat[i].y + 12,
    523                                         0xfe, 150 /*_activeChat[i].field_8*/, 0x0, 0, Screen::FID_GOLDFONT_FNT);
    524                         } else
    525                                 _activeChat[i].duration = -1;
    526                 }
     1010        if (_activeWSA[wsaNum].movie->opened())
     1011                _activeWSA[wsaNum].movie->close();
     1012
     1013        _activeWSA[wsaNum].movie->open(s.wsaFile, 0, 0);
     1014
     1015        if(!_activeWSA[wsaNum].movie->opened()) {
     1016                delete _activeWSA[wsaNum].movie;
     1017                _activeWSA[wsaNum].movie = 0;
     1018                return;
    5271019        }
    528 }
    5291020
    530 void KyraEngine_v2::seq_playWSAs() {
    531         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_playWSAs()");
     1021        _activeWSA[wsaNum].endFrame = s.endFrame;
     1022        _activeWSA[wsaNum].startFrame = _activeWSA[wsaNum].currentFrame = s.startframe;
     1023        _activeWSA[wsaNum].frameDelay = s.frameDelay;
     1024        _activeWSA[wsaNum].movie->setX(0);
     1025        _activeWSA[wsaNum].movie->setY(0);     
     1026        _activeWSA[wsaNum].movie->setDrawPage(_screen->_curPage);
     1027        _activeWSA[wsaNum].callback = s.callback;       
     1028        _activeWSA[wsaNum].control = s.wsaControl;
     1029
     1030        _activeWSA[wsaNum].flags = s.flags | 1;
     1031        _activeWSA[wsaNum].x = s.x;
     1032        _activeWSA[wsaNum].y = s.y;
     1033        _activeWSA[wsaNum].startupCommand = s.startupCommand;
     1034        _activeWSA[wsaNum].finalCommand = s.finalCommand;
     1035        _activeWSA[wsaNum].lastFrame = 0xffff;
    5321036       
    533         uint32 currTime = _system->getMillis();
     1037        seq_nestedSequenceFrame(s.startupCommand, wsaNum);
    5341038
    535         for (int i = 0; i < 8; i++) {
    536                         int currentFrame, frameDelay;
     1039        if (!s.startupCommand)
     1040                seq_processNextSubFrame(wsaNum);
    5371041
    538                         if (_activeWSA[i].control) {
    539                                 int8 nextFrame = _activeWSA[i].control[_activeWSA[i].currentFrame].frameIndex;
    540                                 if (nextFrame == -1)
    541                                         continue;
    542                                
    543                                 currentFrame = nextFrame;
    544                                 frameDelay = _activeWSA[i].control[_activeWSA[i].currentFrame].frameDelay;                             
    545                         } else {
    546                                 if (_activeWSA[i].currentFrame >= _activeWSA[i].endFrame)
    547                                         continue;                               
     1042        _activeWSA[wsaNum].nextFrame = _system->getMillis();
     1043}
    5481044
    549                                 currentFrame = _activeWSA[i].currentFrame;
    550                                 frameDelay = _activeWSA[i].frameDelay;
    551                         }
     1045void KyraEngine_v2::seq_nestedSequenceFrame(int command, int wsaNum) {
     1046        int xa = 0, ya = 0;
     1047        command--;
     1048        if (!_activeWSA[wsaNum].movie)
     1049                return;
    5521050
    553                         _activeWSA[i].movie->displayFrame(currentFrame);
     1051        switch (command) {
     1052        case 0:
     1053                _activeWSA[wsaNum].movie->setDrawPage(8);
     1054                xa = -_activeWSA[wsaNum].movie->xAdd();
     1055                ya = -_activeWSA[wsaNum].movie->yAdd();
     1056                _activeWSA[wsaNum].movie->setX(xa);
     1057                _activeWSA[wsaNum].movie->setY(ya);
     1058                _activeWSA[wsaNum].movie->displayFrame(0, 0);
     1059                _activeWSA[wsaNum].movie->setX(0);
     1060                _activeWSA[wsaNum].movie->setY(0);
     1061                seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
     1062                                                _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 2);
     1063                break;
    5541064
    555                         if (_activeWSA[i].movie && currTime >= _activeWSA[i].nextFrame) {
    556                                 if (_activeWSA[i].callback != 0)
    557                                         (*this.*_activeWSA[i].callback)(currentFrame);
    558                                 _activeWSA[i].currentFrame++;
    559                                 _activeWSA[i].nextFrame = currTime + frameDelay * _tickLength;
    560                         }
     1065        case 1:
     1066                _activeWSA[wsaNum].movie->setDrawPage(8);
     1067                xa = -_activeWSA[wsaNum].movie->xAdd();
     1068                ya = -_activeWSA[wsaNum].movie->yAdd();
     1069                _activeWSA[wsaNum].movie->setX(xa);
     1070                _activeWSA[wsaNum].movie->setY(ya);
     1071                _activeWSA[wsaNum].movie->displayFrame(0, 0);
     1072                _activeWSA[wsaNum].movie->setX(0);
     1073                _activeWSA[wsaNum].movie->setY(0);
     1074                seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
     1075                                                _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 1, 1);
     1076                break;
     1077
     1078        case 2:
     1079                seq_waitForTextsTimeout();
     1080                _activeWSA[wsaNum].movie->setDrawPage(8);
     1081                xa = -_activeWSA[wsaNum].movie->xAdd();
     1082                ya = -_activeWSA[wsaNum].movie->yAdd();
     1083                _activeWSA[wsaNum].movie->setX(xa);
     1084                _activeWSA[wsaNum].movie->setY(ya);
     1085                _activeWSA[wsaNum].movie->displayFrame(0x15, 0);
     1086                _activeWSA[wsaNum].movie->setX(0);
     1087                _activeWSA[wsaNum].movie->setY(0);
     1088                seq_animatedSubFrame(8, 2, 7, 8, _activeWSA[wsaNum].movie->xAdd(), _activeWSA[wsaNum].movie->yAdd(),
     1089                                                _activeWSA[wsaNum].movie->width(), _activeWSA[wsaNum].movie->height(), 0, 2);
     1090                break;
     1091
     1092        case 3:
     1093                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer1);
     1094                _activeWSA[wsaNum].movie->setDrawPage(2);
     1095                _activeWSA[wsaNum].movie->setX(0);
     1096                _activeWSA[wsaNum].movie->setY(0);
     1097                _activeWSA[wsaNum].movie->displayFrame(0, 0);
     1098                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     1099                seq_cmpFadeFrame("scene2.cmp");
     1100                break;
     1101
     1102        case 4:
     1103                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer1);
     1104                _activeWSA[wsaNum].movie->setDrawPage(2);
     1105                _activeWSA[wsaNum].movie->setX(0);
     1106                _activeWSA[wsaNum].movie->setY(0);
     1107                _activeWSA[wsaNum].movie->displayFrame(0, 0);
     1108                _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     1109                seq_cmpFadeFrame("scene3.cmp");
     1110                break;
     1111
     1112        default:
     1113                break;
    5611114        }
    5621115}
    5631116
    564 void KyraEngine_v2::seq_loadWSA(int wsaNum, const char *filename, int frameDelay,
    565                                                                 void (KyraEngine_v2::*callback)(int), const SequenceControl *control) {
     1117void KyraEngine_v2::seq_animatedSubFrame(int srcPage, int dstPage,
     1118        int delaytime, int steps, int x, int y, int w, int h, int openClose, int directionFlags) {
     1119        if (openClose) {
     1120                for (int i = 1; i < steps; i++) {
     1121                        uint32 endtime = _system->getMillis() + delaytime * _tickLength;
    5661122
    567         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_loadWSA(%i, %s, %i, %i)", wsaNum, filename, frameDelay, callback ? true : false);
    568        
    569         _activeWSA[wsaNum].movie = new WSAMovieV2(this);
    570         assert(_activeWSA[wsaNum].movie);
    571         _activeWSA[wsaNum].endFrame = _activeWSA[wsaNum].movie->open(filename, 0, _screen->_currentPalette);
    572         _activeWSA[wsaNum].movie->flagOldOff(true);
    573         assert(_activeWSA[wsaNum].movie->opened());
    574         _activeWSA[wsaNum].currentFrame = 0;
    575         _activeWSA[wsaNum].frameDelay = frameDelay;
    576         _activeWSA[wsaNum].nextFrame = _system->getMillis();
    577         _activeWSA[wsaNum].movie->setX(0);
    578         _activeWSA[wsaNum].movie->setY(0);     
    579         _activeWSA[wsaNum].movie->setDrawPage(_screen->_curPage);
    580         _activeWSA[wsaNum].callback = callback;
    581         _activeWSA[wsaNum].control = control;
     1123                        int w2 = (((w << 8) / steps) * i) >> 8;
     1124                        int h2 = (((h << 8) / steps) * i) >> 8;
     1125
     1126                        int ym = (directionFlags & 2) ? (h - h2) : 0;
     1127                        int xm = (directionFlags & 1) ? (w - w2) : 0;
     1128
     1129                        _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0);
     1130
     1131                        _screen->copyPage(dstPage, 6);
     1132                        _screen->copyPage(dstPage, 0);
     1133                        _screen->updateScreen();
     1134
     1135                        _screen->copyBlockToPage(dstPage, 0, 0, 320, 200, _pageBuffer2);
     1136                        delayUntil(endtime);
     1137                }
     1138
     1139                _screen->wsaFrameAnimationStep(0, 0, x, y, w, h, w, h, srcPage, dstPage, 0);
     1140                _screen->copyPage(dstPage, 6);
     1141                _screen->copyPage(dstPage, 0);
     1142                _screen->updateScreen();
     1143        } else {
     1144                _screen->copyBlockToPage(dstPage, 0, 0, 320, 200, _pageBuffer2);
     1145                for (int i = steps; i; i--) {
     1146                        uint32 endtime = _system->getMillis() + delaytime * _tickLength;
     1147
     1148                        int w2 = (((w << 8) / steps) * i) >> 8;
     1149                        int h2 = (((h << 8) / steps) * i) >> 8;
     1150
     1151                        int ym = (directionFlags & 2) ? (h - h2) : 0;
     1152                        int xm = (directionFlags & 1) ? (w - w2) : 0;
     1153
     1154                        _screen->wsaFrameAnimationStep(0, 0, x + xm, y + ym, w, h, w2, h2, srcPage, dstPage, 0);
     1155
     1156                        _screen->copyPage(dstPage, 6);
     1157                        _screen->copyPage(dstPage, 0);
     1158                        _screen->updateScreen();
     1159
     1160                        _screen->copyBlockToPage(dstPage, 0, 0, 320, 200, _pageBuffer2);
     1161                        delayUntil(endtime);
     1162                }
     1163        }
    5821164}
    5831165
     1166void KyraEngine_v2::seq_resetActiveWSA(int wsaNum) {
     1167        if (_activeWSA[wsaNum].flags == -1)
     1168                return;
     1169
     1170        _activeWSA[wsaNum].flags = -1;
     1171        seq_nestedSequenceFrame(_activeWSA[wsaNum].finalCommand, wsaNum);
     1172        _activeWSA[wsaNum].movie->close();
     1173}
     1174
    5841175void KyraEngine_v2::seq_unloadWSA(int wsaNum) {
    585         debugC(9, kDebugLevelMain, "KyraEngine_v2::seq_unloadWSA(%i)", wsaNum);
    586        
    5871176        if (_activeWSA[wsaNum].movie) {
    5881177                _activeWSA[wsaNum].movie->close();
    5891178                delete _activeWSA[wsaNum].movie;
     
    5911180        }
    5921181}
    5931182
     1183bool KyraEngine_v2::seq_processNextSubFrame(int wsaNum) {
     1184        uint32 cframe = _activeWSA[wsaNum].currentFrame;
     1185        uint32 ctime = _system->getMillis();
     1186       
     1187        if (_activeWSA[wsaNum].callback && cframe != _activeWSA[wsaNum].lastFrame) {
     1188                _activeWSA[wsaNum].lastFrame = cframe;
     1189                cframe = (this->*_activeWSA[wsaNum].callback)(_activeWSA[wsaNum].movie, _activeWSA[wsaNum].x, _activeWSA[wsaNum].y, cframe);           
     1190        }
     1191
     1192        if (_activeWSA[wsaNum].movie) {
     1193                _activeWSA[wsaNum].movie->setDrawPage(2);
     1194                _activeWSA[wsaNum].movie->setX(_activeWSA[wsaNum].x);
     1195                _activeWSA[wsaNum].movie->setY(_activeWSA[wsaNum].y);
     1196               
     1197                if (_activeWSA[wsaNum].flags & 0x20) {
     1198                        _activeWSA[wsaNum].movie->displayFrame(_activeWSA[wsaNum].control[cframe].frameIndex, 0x4000);
     1199                        _activeWSA[wsaNum].frameDelay = _activeWSA[wsaNum].control[cframe].frameDelay;
     1200                } else {
     1201                        _activeWSA[wsaNum].movie->displayFrame(cframe % _activeWSA[wsaNum].movie->frames(), 0x4000);
     1202                }
     1203        }
     1204
     1205        if (_activeWSA[wsaNum].flags & 0x10) {
     1206                cframe = (ctime - _activeWSA[wsaNum].nextFrame) / (_activeWSA[wsaNum].frameDelay * _tickLength);
     1207        } else {
     1208                if (((int32)(ctime - _activeWSA[wsaNum].nextFrame) / (int32)(_activeWSA[wsaNum].frameDelay * _tickLength)) > 0) {
     1209                        cframe++;
     1210                        _activeWSA[wsaNum].nextFrame += (_activeWSA[wsaNum].frameDelay * _tickLength);
     1211                }
     1212        }
     1213       
     1214        bool res = false;
     1215
     1216        if (cframe >= _activeWSA[wsaNum].endFrame) {
     1217                int sw = ((_activeWSA[wsaNum].flags & 0x1e) - 2);
     1218                switch (sw) {
     1219                case 0:
     1220                        res = true;
     1221                        cframe = _activeWSA[wsaNum].endFrame;
     1222                        _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
     1223                        break;
     1224
     1225                case 6:
     1226                case 8:
     1227                        cframe = _activeWSA[wsaNum].endFrame - 1;
     1228                        break;
     1229
     1230                case 2:
     1231                case 10:
     1232                        cframe = _activeWSA[wsaNum].startFrame;
     1233                        break;
     1234
     1235                default:
     1236                        cframe = _activeWSA[wsaNum].endFrame - 1;
     1237                        res = true;
     1238                        break;
     1239                }
     1240        }
     1241
     1242        _activeWSA[wsaNum].currentFrame = cframe & 0xffff;
     1243        return res;
     1244}
     1245
     1246void KyraEngine_v2::seq_init() {
     1247        _pageBuffer1 = new uint8[0xFA00];
     1248        _pageBuffer2 = new uint8[0xFA00];
     1249        _seqProcessedString = new char[200];
     1250        _seqWsa = new WSAMovieV2(this);
     1251        _activeWSA = new ActiveWSA[8];
     1252        _activeText = new ActiveText[10];
     1253}
     1254
     1255void KyraEngine_v2::seq_uninit() {
     1256        delete [] _pageBuffer1;
     1257        delete [] _pageBuffer2;
     1258        delete [] _seqProcessedString;
     1259        delete [] _activeWSA;
     1260        delete [] _activeText;
     1261        delete _seqWsa;
     1262
     1263        _pageBuffer1 = _pageBuffer2 = 0;
     1264        _seqProcessedString = 0;
     1265        _activeWSA = 0;
     1266        _activeText = 0;
     1267        _seqWsa = 0;
     1268}
     1269
     1270// static res
     1271// TODO: move to staticres.cpp
     1272
     1273const Sequence KyraEngine_v2::_sequences[] = {
     1274        { 2, 0, "virgin.cps", 4, 0, 0xFFFF, 0xFFFF, 0, 1, 0x64, 0, 0, 0, 0x1E},
     1275        { 1, "westwood.wsa",    0, 4, 0, 0xFFFF, 0xFFFF, 0, 0x12, 0x0C, 0, 0, &KyraEngine_v2::seq_introWestwood, 0xA0 },
     1276        { 1, "title.wsa", 0, 4, 0, 0xFFFF, 0xFFFF, 0, 0x1A, 0x0C, 0, 0, &KyraEngine_v2::seq_introTitle, 0x0A },
     1277        { 2, 0, "over.cps", 4, 0, 0xFFFF, 0xFFFF, 0, 1, 0x0E10, 0, 0, &KyraEngine_v2::seq_introOverview, 0x1E },
     1278        { 2, 0, "library.cps", 4, 0, 0xFFFF, 0xFFFF, 0, 1, 0x0E10, 0, 0, &KyraEngine_v2::seq_introLibrary, 0x1E },
     1279        { 2, 0, "hand.cps", 4, 0, 0xFFFF, 0xFFFF, 0, 1, 0x0E10, 0, 0, &KyraEngine_v2::seq_introHand, 0x5A },
     1280        { 1, "point.wsa", 0, 4, 8, 0xFFFF, 0xFFFF, 0, 0x26, 7, 0, 0, &KyraEngine_v2::seq_introPoint, 0xC8 },
     1281        { 1, "zanfaun.wsa", 0, 4, 0, 0xFFFF, 0xFFFF, 0, 0x33, 0x10, 0, 0, &KyraEngine_v2::seq_introZanfaun, 0xF0 },
     1282};
     1283
     1284const NestedSequence KyraEngine_v2::_nSequences[] = {
     1285        { 0x0C, "figgle.wsa", 0, 3, 0x3C, /*&KyraEngine_v2::seq_finaleFiggle*/0, 0, 0, 0, 0, 0, 0 },
     1286
     1287        { 8, "over1.wsa", 0, 0x0A, 0x0A, &KyraEngine_v2::seq_introOver1, 0, 0, 0, 0, 0, 0 },
     1288        { 8, "over2.wsa", 0, 0x0B, 9, &KyraEngine_v2::seq_introOver2, 0, 0, 0, 0, 0, 0 },
     1289        { 8, "forest.wsa", 0, 0x16, 6, &KyraEngine_v2::seq_introForest, 0, 0, 0, 1, 3, 0 },
     1290        { 8, "dragon.wsa", 0, 0x0B, 6, &KyraEngine_v2::seq_introDragon, 0, 0, 0, 2, 0, 0 },
     1291        { 2, "darm.wsa", 0, 0x13, 9, &KyraEngine_v2::seq_introDarm, 0, 0, 0, 4, 0, 0 },
     1292        { 2, "library.wsa", 0, 0x21, 9, &KyraEngine_v2::seq_introLibrary2, 0, 0, 0, 4, 0, 0 },
     1293        { 0x2A, "library.wsa", 0, 0x13, 9, &KyraEngine_v2::seq_introLibrary2, 0, 0, _wsaControlLibrary, 0, 0, 0 },
     1294        { 0x0A, "marco.wsa", 0, 0x25, 9, &KyraEngine_v2::seq_introMarco, 0, 0, 0, 4, 0, 0 },
     1295        { 2, "hand1a.wsa", 0, 0x22, 9, &KyraEngine_v2::seq_introHand1a, 0, 0, 0, 0, 0, 0 },
     1296        { 0x2A, "hand1b.wsa", 0, 0x10, 9, &KyraEngine_v2::seq_introHand1b, 0, 0, _wsaControlHand1b, 0, 0, 0 },
     1297        { 0x2A, "hand1c.wsa", 0, 9, 9, &KyraEngine_v2::seq_introHand1c, 0, 0, _wsaControlHand1c, 0, 0, 0 },
     1298        { 0x2C, "hand2.wsa", 0, 2, 9, &KyraEngine_v2::seq_introHand2, 0, 0, _wsaControlHand2, 5, 0, 0 },
     1299        { 0x2C, "hand3.wsa", 0, 4, 9, &KyraEngine_v2::seq_introHand3, 0, 0, _wsaControlHand3, 5, 0, 0 },
     1300        { 0x2C, "hand4.wsa", 0, 8, 9, 0, 0, 0, _wsaControlHand4, 5, 0, 0 }
     1301};
     1302
     1303
     1304const SequenceControl KyraEngine_v2::_wsaControlLibrary[] = {
     1305        {0x00, 0x0A}, {0x01, 0x0A}, {0x02, 0x0A}, {0x03, 0x0A}, {0x04, 0x0A}, {0x05, 0x0A},
     1306        {0x06, 0x0A}, {0x07, 0x0A}, {0x08, 0x0A}, {0x09, 0x0A}, {0x08, 0x0A}, {0x07, 0x0A},
     1307        {0x06, 0x0A}, {0x05, 0x28}, {0x04, 0x0A}, {0x03, 0x0A}, {0x02, 0x0A}, {0x01, 0x0A}
     1308};
     1309
     1310const SequenceControl KyraEngine_v2::_wsaControlHand1b[] = {
     1311        {0x00, 0x06}, {0x01, 0x06}, {0x02, 0x06}, {0x03, 0x06}, {0x04, 0x06}, {0x05, 0x06},
     1312        {0x06, 0x06}, {0x07, 0x06}, {0x08, 0x06}, {0x09, 0x06}, {0x0A, 0x06}, {0x0B, 0x06},
     1313        {0x0B, 0x0C}, {0x0C, 0x0C}, {0x0D, 0x0C}, {0x0C, 0x0C}, {0x0B, 0x0C}
     1314};
     1315
     1316const SequenceControl KyraEngine_v2::_wsaControlHand1c[] = {
     1317        {0x00, 0x06}, {0x01, 0x06}, {0x02, 0x06}, {0x03, 0x06}, {0x04, 0x06}, {0x03, 0x06},
     1318        {0x04, 0x06}, {0x05, 0x40}, {0x05, 0x06}
     1319};
     1320 
     1321const SequenceControl KyraEngine_v2::_wsaControlHand2[] = {
     1322        {0x00, 0x06}, {0x01, 0x06}, {0x00, 0x06}, {0x01, 0x06}, {0x00, 0x06}, {0x01, 0x06},
     1323        {0x00, 0x06}, {0x01, 0x06}, {0x00, 0x06}, {0x01, 0x06}, {0x00, 0x06}, {0x01, 0x06},
     1324        {0x00, 0x06}, {0x01, 0x06}, {0x00, 0x06}, {0x01, 0x06} 
     1325};
     1326
     1327const SequenceControl KyraEngine_v2::_wsaControlHand3[] = {
     1328        {0x00, 0x06}, {0x01, 0x06}, {0x02, 0x06}, {0x01, 0x06}, {0x00, 0x01}
     1329};
     1330
     1331const SequenceControl KyraEngine_v2::_wsaControlHand4[] = {
     1332        {0x00, 0x06}, {0x01, 0x06}, {0x02, 0x06}, {0x03, 0x06}, {0x04, 0x06},
     1333        {0x03, 0x06}, {0x02, 0x06}, {0x01, 0x06}
     1334};
     1335
    5941336} // end of namespace Kyra
    5951337
  • staticres.cpp

     
    11541154
    11551155// kyra 2 static res
    11561156
    1157 const char *KyraEngine_v2::_introStrings[] = {
     1157const char *KyraEngine_v2::_sequenceStrings[] = {
    11581158        "Kyrandia is disappearing!",
    11591159        "Rock by rock...",
    11601160        "...and tree by tree.",
     
    11751175        " DUMMY STRING... ",
    11761176        "If they think I'm going to walk all the way down there, they're nuts!",
    11771177        " DUMMY STRING... ",
    1178         "Hurry up faun!"
     1178        " DUMMY STRING... ",
     1179        "Hurry up Faun!",
     1180
     1181        "Boy, that was a close call!",
     1182        "You said it pal. I, for one, am never going hunting again!",
     1183        "Ribbit.",
     1184        "How many times do I have to tell you? You're a toad.",
     1185        "Oh no! We're out of cheese!",
     1186        "Let's try this earwax. It's orange.",
     1187        "Mommy, when do I get the ivy?",
     1188        "Get out of here, shoo!",
     1189        "You cut, and I'll choose.",
     1190        "No. You cut and I'll choose.",
     1191        "I still say it was derivative drivel.",
     1192        "Aw, you still wouldn't recognize iambic pentameter if it bit you on the butt!",
     1193
     1194        "Executive Producer",
     1195        "Brett W. Sperry",
     1196        "Designed & Directed by",
     1197        "Rick Gush",
     1198        "Lead Programmer",
     1199        "Michael Legg",
     1200        "Art Management",
     1201        "Louis Castle",
     1202        "Joseph B. Hewitt IV",
     1203        "Lead Artist",
     1204        "Rick Parks",
     1205        "Additional Coding by",
     1206        "Philip W. Gorrow",
     1207        "Matt Collins",
     1208        "Mark McCubbin",
     1209        "Artists",
     1210        "Cameron Chun",
     1211        "Cary Averett",
     1212        "Cindy Chinn",
     1213        "Elie Arabian",
     1214        "Fei Cheng",
     1215        "Ferby Miguel",
     1216        "Frank Mendeola",
     1217        "Jack Martin",
     1218        "Jerry Moore",
     1219        "",
     1220        "Judith Peterson",
     1221        "Larry Miller",
     1222        "Lenny Lee",
     1223        "Louise Sandoval",
     1224        "Ren Olsen",
     1225        "Music & Sounds by",
     1226        "Paul Mudra",
     1227        "Frank Klepacki",
     1228        "Dwight Okahara",
     1229        "Pat Collins",
     1230        "Qualilty Assurance by",
     1231        "Glenn Sperry",
     1232        "Michael Lightner",
     1233        "William Foster",
     1234        "Jesse Clemit",
     1235        "Jeff Fillhaber",
     1236        "Manual, Package Design",
     1237        "& Fulfillment",
     1238        "Eydie Laramore",
     1239        "Lisa Marcinko",
     1240        "Lauren Rifkin",
     1241        "Congratulations!",
     1242        "Thank you for playing The Hand of Fate!",
     1243        "Guest Coding",
     1244        "Producer Liaison",
     1245        "Scott Duckett",
     1246        "Irvine Testers",
     1247        "Chris McFarland",
     1248        "Paul Moore",
     1249        "Chad Soares",
     1250        "Jared Brinkley",
     1251        "Jon Willliams",
     1252        "Chris Toft",
     1253        "Chris's Hair by",
     1254        "Cumulo Nimbus",
     1255        "Load a game",
     1256        "Introduction",
     1257        "Start a new game",
     1258        "Exit the game",
     1259        "Special Thanks to",
     1260        "Sake Joe Bostic-san",
     1261        "Tim Fritz",
     1262        "Kenny Dunne",
     1263        "Yukio Sekiguchi (Japan)",
     1264        "Takeshi Abo (Japan)"
    11791265};
    11801266
    1181 const int KyraEngine_v2::_introStringsSize = ARRAYSIZE(KyraEngine_v2::_introStrings);
     1267const int KyraEngine_v2::_sequenceStringsSize = ARRAYSIZE(KyraEngine_v2::_sequenceStrings);
    11821268
    1183 const char *KyraEngine_v2::_introSoundList[] = {
     1269const char *KyraEngine_v2::_sequenceSoundListPC[] = {
    11841270        "eintro1",
    11851271        "eintro2",
    11861272        "eintro3",
     
    11981284        "0000130",
    11991285        "0000180",
    12001286        "0000160",
     1287
    12011288        "asong",
    12021289        "crowcaw",
    12031290        "eyerub2",
     
    12081295        "lambmom3",
    12091296        "lambkid1",
    12101297        "thunder2",
    1211         "tunder3",
     1298        "thunder3",
    12121299        "wind6",
    12131300        "h2odrop2",
    12141301        "gasleak",
     
    12301317        "theend"
    12311318};
    12321319
    1233 const int KyraEngine_v2::_introSoundListSize = ARRAYSIZE(KyraEngine_v2::_introSoundList);
     1320const int KyraEngine_v2::_sequenceSoundListPCSize = ARRAYSIZE(KyraEngine_v2::_sequenceSoundListPC);
    12341321
     1322const uint8 KyraEngine_v2::_seqTextColorPresets[] = { 0x01, 0x01, 0x00, 0x3f, 0x3f, 0x3f };
     1323
    12351324const char *KyraEngine_v2::_languageExtension[] = {
    12361325        "ENG",
    12371326        "FRE",
     
    13951484
    13961485} // End of namespace Kyra
    13971486
     1487
  • wsamovie.cpp

     
    398398        _frameOffsTable = new uint32[_numFrames + 2];
    399399        _frameOffsTable[0] = 0;
    400400        uint32 frameDataOffs = READ_LE_UINT32(wsaData); wsaData += 4;
     401        bool firstFrame = true;
     402        if (frameDataOffs == 0) {
     403                firstFrame = false;
     404                frameDataOffs = READ_LE_UINT32(wsaData);
     405                _flags |= WF_NO_FIRST_FRAME;
     406        }
     407
    401408        for (int i = 1; i < _numFrames + 2; ++i) {
    402409                _frameOffsTable[i] = READ_LE_UINT32(wsaData) - frameDataOffs;
    403410                wsaData += 4;
     
    412419        memcpy(_frameData, wsaData, frameDataSize);
    413420
    414421        // decode first frame
    415         Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize);
     422        if (firstFrame)
     423                Screen::decodeFrame4(_frameData, _deltaBuffer, _deltaBufferSize);
    416424
    417425        delete [] p;
    418426        _opened = true;
     
    483491        if (_flags & WF_OFFSCREEN_DECODE) {
    484492                if (_oldOff) {
    485493                        // Kyrandia 1 offscreen buffer -> screen copy method of Kyrandia 1, needs to be present
    486                         // for our intro code that doesn't supply all the needed parameters for the Kyrandia 2 method
     494                        // for our Kyrandia 3 menu code
    487495                        _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer);
    488496                } else {
    489497                        // This is the offscreen buffer -> screen copy method of Kyrandia 2 as it's implemented
    490                         // in the original, we use this in game
     498                        // in the original
    491499                        Screen_v2 *screen = _vm->screen_v2();
    492500                        int pageBackUp = screen->_curPage;
    493501                        screen->_curPage = _drawPage;
     
    512520
    513521} // end of namespace Kyra
    514522
     523
  • wsamovie.h

     
    125125       
    126126        int width() const { return _width; }
    127127        int height() const { return _height; }
     128
     129        void setWidth(int w) { _width = w; }
     130        void setHeight(int h) { _height = h; }
    128131       
    129132        // HACK for our intro code
    130133        void flagOldOff(bool enabled) { _oldOff = enabled; }
     
    140143
    141144#endif
    142145
     146