1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #ifdef ENABLE_EOB
24
25 #include "kyra/engine/darkmoon.h"
26 #include "kyra/graphics/screen_eob.h"
27 #include "kyra/resource/resource.h"
28 #include "kyra/sound/sound.h"
29
30 #include "common/system.h"
31
32 #include "base/version.h"
33
34 namespace Kyra {
35
36 class DarkmoonSequenceHelper {
37 friend class DarkMoonEngine;
38 public:
39 enum Mode {
40 kIntro,
41 kFinale
42 };
43
44 DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_EoB *screen, Mode mode);
45 ~DarkmoonSequenceHelper();
46
47 void loadScene(int index, int pageNum, bool ignorePalette = false);
48 void animCommand(int index, int del = -1);
49 void setPlatformAnimIndexOffset(int offset);
50
51 void printText(int index, int color);
52 void fadeText();
53
54 void update(int srcPage);
55
56 void setPalette(int index);
57 void fadePalette(int index, int del);
58 void copyPalette(int srcIndex, int destIndex);
59
60 void initDelayedPaletteFade(int palIndex, int rate);
61 bool processDelayedPaletteFade();
62
63 void delay(uint32 ticks);
64 void waitForSongNotifier(int index, bool introUpdateAnim = false);
65 void updateAmigaSound();
66
67 private:
68 void init(Mode mode);
69 void setPaletteWithoutTextColor(int index);
70
71 OSystem *_system;
72 DarkMoonEngine *_vm;
73 Screen_EoB *_screen;
74
75 struct Config {
ConfigKyra::DarkmoonSequenceHelper::Config76 Config(const char *const *str, const char *const *cpsfiles, const uint8 **cpsdata, const char *const *pal, const DarkMoonShapeDef **shp, const DarkMoonAnimCommand **anim, bool loadScenePalette, bool paletteFading, bool animCmdRestorePalette, bool shapeBackgroundFading, int animPalOffset, int animType1ShapeDim, bool animCmd5SetPalette, int animCmd5ExtraPage) : strings(str), cpsFiles(cpsfiles), cpsData(cpsdata), palFiles(pal), shapeDefs(shp), animData(anim), loadScenePal(loadScenePalette), palFading(paletteFading), animCmdRestorePal(animCmdRestorePalette), shpBackgroundFading(shapeBackgroundFading), animPalOffs(animPalOffset), animCmd1ShapeFrame(animType1ShapeDim), animCmd5SetPal(animCmd5SetPalette), animCmd5AltPage(animCmd5ExtraPage) {}
77 const char *const *strings;
78 const char *const *cpsFiles;
79 const uint8 **cpsData;
80 const char *const *palFiles;
81 const DarkMoonShapeDef **shapeDefs;
82 const DarkMoonAnimCommand **animData;
83 bool loadScenePal;
84 bool palFading;
85 bool animCmdRestorePal;
86 bool shpBackgroundFading;
87 int animPalOffs;
88 int animCmd1ShapeFrame;
89 bool animCmd5SetPal;
90 int animCmd5AltPage;
91 };
92
93 const Config *_config;
94
95 Palette *_palettes[13];
96 uint8 *_fadingTables[7];
97
98 const uint8 **_shapes;
99
100 uint32 _fadePalTimer;
101 int _fadePalRate;
102 int _fadePalIndex;
103
104 uint8 _sndNextTrack;
105 uint16 _sndNextTrackMarker;
106 const uint16 *_sndMarkersFMTowns;
107
108 uint8 _textColor[3];
109
110 int _platformAnimOffset;
111
112 Screen::FontId _prevFont;
113
114 static const char *const _palFilesIntroVGA[];
115 static const char *const _palFilesIntroEGA[];
116 static const char *const _palFilesFinaleVGA[];
117 static const char *const _palFilesFinaleEGA[];
118 static const char *const _palFilesFinaleAmiga[];
119 };
120
mainMenu()121 int DarkMoonEngine::mainMenu() {
122 int menuChoice = _menuChoiceInit;
123 _menuChoiceInit = 0;
124
125 _sound->selectAudioResourceSet(kMusicIntro);
126 _sound->loadSoundFile(0);
127
128 Screen::FontId of = _screen->_currentFont;
129 int op = 0;
130 Common::SeekableReadStream *s = 0;
131
132 while (menuChoice >= 0 && !shouldQuit()) {
133 switch (menuChoice) {
134 case 0: {
135 if (_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformAmiga) {
136 _screen->loadPalette("MENU.PAL", _screen->getPalette(0));
137 _screen->setScreenPalette(_screen->getPalette(0));
138 _screen->loadEoBBitmap("MENU", 0, 3, 3, 2);
139 } else {
140 s = _res->createReadStream("XENU.CPS");
141 if (s) {
142 s->read(_screen->getPalette(0).getData(), 768);
143 _screen->loadFileDataToPage(s, 3, 64000);
144 delete s;
145 } else {
146 _screen->loadBitmap("MENU.CPS", 3, 3, &_screen->getPalette(0));
147 }
148
149 if (_configRenderMode == Common::kRenderEGA)
150 _screen->loadPalette("MENU.EGA", _screen->getPalette(0));
151 }
152
153 _screen->setScreenPalette(_screen->getPalette(0));
154 _screen->convertPage(3, 2, 0);
155
156 of = _screen->setFont(Screen::FID_6_FNT);
157 op = _screen->setCurPage(2);
158 Common::String versionString(Common::String::format("ScummVM %s", gScummVMVersion));
159 _screen->printText(versionString.c_str(), 267 - versionString.size() * 6, _flags.platform == Common::kPlatformFMTowns ? 152 : 160, _flags.platform == Common::kPlatformAmiga ? 18 : 13, 0);
160 _screen->setFont(of);
161 _screen->_curPage = op;
162 _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
163 _screen->shadeRect(78, 99, 249, 141, 4);
164 _screen->showMouse();
165 _screen->updateScreen();
166 _allowImport = true;
167 menuChoice = mainMenuLoop();
168 _allowImport = false;
169 } break;
170
171 case 1:
172 // load game in progress
173 menuChoice = -1;
174 break;
175
176 case 2:
177 // create new party
178 menuChoice = -2;
179 break;
180
181 case 3:
182 // transfer party
183 menuChoice = -3;
184 break;
185
186 case 4:
187 // play intro
188 seq_playIntro();
189 menuChoice = 0;
190 break;
191
192 case 5:
193 // quit
194 menuChoice = -5;
195 break;
196
197 default:
198 break;
199 }
200 }
201
202 return shouldQuit() ? -5 : menuChoice;
203 }
204
mainMenuLoop()205 int DarkMoonEngine::mainMenuLoop() {
206 int sel = -1;
207 do {
208 _screen->setScreenDim(6);
209 _gui->simpleMenu_setup(6, 0, _mainMenuStrings, -1, 0, 0, _configRenderMode == Common::kRenderCGA ? 1 : guiSettings()->colors.guiColorWhite, guiSettings()->colors.guiColorLightRed, guiSettings()->colors.guiColorBlack);
210 _screen->updateScreen();
211
212 while (sel == -1 && !shouldQuit())
213 sel = _gui->simpleMenu_process(6, _mainMenuStrings, 0, -1, 0);
214 } while ((sel < 0 || sel > 5) && !shouldQuit());
215
216 if (_flags.platform == Common::kPlatformFMTowns && sel == 2) {
217 townsUtilitiesMenu();
218 sel = -1;
219 }
220
221 return sel + 1;
222 }
223
townsUtilitiesMenu()224 void DarkMoonEngine::townsUtilitiesMenu() {
225 _screen->copyRegion(78, 99, 78, 99, 172, 43, 2, 0, Screen::CR_NO_P_CHECK);
226 int sel = -1;
227 do {
228 _gui->simpleMenu_setup(8, 0, _utilMenuStrings, -1, 0, 0, _configRenderMode == Common::kRenderCGA ? 1 : guiSettings()->colors.guiColorWhite, guiSettings()->colors.guiColorLightRed, guiSettings()->colors.guiColorBlack);
229 _screen->updateScreen();
230 while (sel == -1 && !shouldQuit())
231 sel = _gui->simpleMenu_process(8, _utilMenuStrings, 0, -1, 0);
232 if (sel == 0) {
233 _config2431 ^= true;
234 sel = -1;
235 }
236 } while ((sel < 0 || sel > 1) && !shouldQuit());
237 }
238
seq_playIntro()239 void DarkMoonEngine::seq_playIntro() {
240 DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kIntro);
241
242 _screen->setCurPage(0);
243 _screen->clearCurPage();
244
245 snd_stopSound();
246
247 sq.loadScene(4, 2);
248
249 uint8 textColor1 = 16;
250 uint8 textColor2 = 15;
251
252 if (_flags.platform == Common::kPlatformAmiga) {
253 textColor1 = textColor2 = 31;
254 sq.loadScene(13, 2);
255 sq.loadScene(14, 2);
256 sq.loadScene(15, 2);
257 } else if (_configRenderMode == Common::kRenderEGA) {
258 textColor1 = 15;
259 }
260
261 sq.loadScene(0, 2);
262 sq.delay(1);
263
264 if (!skipFlag() && !shouldQuit())
265 snd_playSong(12);
266
267 _screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
268 sq.setPalette(9);
269 sq.fadePalette(0, 3);
270
271 _screen->setCurPage(2);
272 _screen->setClearScreenDim(17);
273 _screen->setCurPage(0);
274
275 removeInputTop();
276 sq.delay(18);
277
278 sq.animCommand(3, 18);
279 sq.animCommand(6, 18);
280 sq.animCommand(0);
281
282 sq.waitForSongNotifier(1);
283
284 sq.animCommand(_configRenderMode == Common::kRenderEGA ? 12 : 11);
285 sq.animCommand(7, 6);
286 sq.animCommand(2, 6);
287
288 sq.waitForSongNotifier(2);
289
290 sq.animCommand(_flags.platform == Common::kPlatformAmiga ? 37 : (_configRenderMode == Common::kRenderEGA ? 39 : 38));
291 sq.animCommand(3);
292 sq.animCommand(8);
293 sq.animCommand(1, 10);
294 sq.animCommand(0, 6);
295 sq.animCommand(2);
296
297 sq.waitForSongNotifier(3);
298
299 _screen->setClearScreenDim(17);
300 _screen->setCurPage(2);
301 _screen->setClearScreenDim(17);
302 _screen->setCurPage(0);
303
304 sq.animCommand(_flags.platform == Common::kPlatformAmiga ? 38 : (_configRenderMode == Common::kRenderEGA ? 41 : 40));
305 sq.animCommand(7, 18);
306
307 if (_flags.platform == Common::kPlatformAmiga)
308 sq.fadeText();
309
310 sq.printText(0, textColor1); // You were settling...
311 sq.animCommand(7, 90);
312 sq.fadeText();
313
314 sq.printText(1, textColor1); // Then a note was slipped to you
315 sq.animCommand(8);
316 sq.animCommand(2, 72);
317 sq.fadeText();
318
319 sq.printText(2, textColor1); // It was from your friend Khelben Blackstaff...
320 sq.animCommand(2);
321 sq.animCommand(6, 36);
322 sq.animCommand(3);
323 sq.fadeText();
324
325 sq.printText(3, textColor1); // The message was urgent.
326
327 sq.loadScene(1, 2);
328 sq.waitForSongNotifier(4);
329
330 // intro scroll
331 if (!skipFlag() && !shouldQuit()) {
332 if (_configRenderMode == Common::kRenderEGA) {
333 for (int i = 0; i < 35; i++) {
334 uint32 endtime = _system->getMillis() + 2 * _tickLength;
335 _screen->copyRegion(16, 8, 8, 8, 296, 128, 0, 0, Screen::CR_NO_P_CHECK);
336 _screen->copyRegion(i << 3, 0, 304, 8, 8, 128, 2, 0, Screen::CR_NO_P_CHECK);
337 _screen->updateScreen();
338 if (i == 12)
339 sq.animCommand(42);
340 else if (i == 25)
341 snd_playSoundEffect(11);
342 delayUntil(endtime);
343 }
344 } else {
345 for (int i = 0; i < 280; i += 3) {
346 uint32 endtime = _system->getMillis() + _tickLength;
347 _screen->copyRegion(11, 8, 8, 8, 301, 128, 0, 0, Screen::CR_NO_P_CHECK);
348 _screen->copyRegion(i, 0, 309, 8, 3, 128, 2, 0, Screen::CR_NO_P_CHECK);
349 _screen->updateScreen();
350 if (_flags.platform == Common::kPlatformAmiga) {
351 if (i == 4 || i == 24 || i == 36)
352 sq.animCommand(39);
353 } else if (i == 96) {
354 sq.animCommand(42);
355 }
356 delayUntil(endtime);
357 }
358 }
359 }
360
361 _screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
362 sq.animCommand(4);
363 sq.fadeText();
364 sq.delay(10);
365
366 sq.loadScene(2, 2);
367 sq.update(2);
368 sq.delay(10);
369
370 sq.printText(4, textColor1); // What could Khelben want?
371 sq.delay(25);
372
373 sq.loadScene(3, 2);
374 sq.delay(54);
375 sq.animCommand(_flags.platform == Common::kPlatformAmiga ? 12 : 13);
376 _screen->copyRegion(104, 16, 96, 8, 120, 100, 0, 2, Screen::CR_NO_P_CHECK);
377 sq.fadeText();
378
379 if (_flags.platform == Common::kPlatformAmiga)
380 sq.animCommand(9);
381
382 sq.printText(5, textColor2); // Welcome, please come in
383 sq.animCommand(10);
384 sq.animCommand(10);
385 sq.animCommand(9);
386 sq.animCommand(9);
387 sq.fadeText();
388
389 sq.printText(6, textColor2); // Khelben awaits you in his study
390 for (int i = 0; i < 3; i++)
391 sq.animCommand(10);
392 sq.animCommand(9);
393
394 if (_flags.platform == Common::kPlatformAmiga)
395 sq.setPlatformAnimIndexOffset(-1);
396
397 sq.animCommand(14);
398
399 if (_flags.platform == Common::kPlatformAmiga)
400 _sound->beginFadeOut();
401
402 sq.loadScene(5, 2);
403
404 if (!skipFlag() && !shouldQuit()) {
405 if (_flags.platform == Common::kPlatformAmiga) {
406 _screen->fadeToBlack(5);
407 _screen->clearCurPage();
408 _screen->fadeFromBlack(1);
409 sq.fadeText();
410 snd_playSong(14);
411 } else {
412 sq.waitForSongNotifier(5);
413 sq.fadeText();
414 _screen->clearCurPage();
415 _screen->updateScreen();
416 }
417 }
418
419 for (int i = 0; i < 6; i++)
420 sq.animCommand(15);
421
422 if (_configRenderMode == Common::kRenderEGA && !skipFlag() && !shouldQuit()) {
423 _screen->loadPalette("INTRO.EGA", _screen->getPalette(0));
424 _screen->setScreenPalette(_screen->getPalette(0));
425 }
426
427 sq.loadScene(6, 2);
428 sq.loadScene(7, 2);
429 _screen->clearCurPage();
430 sq.update(2);
431
432 if (_flags.platform == Common::kPlatformAmiga && !skipFlag() && !shouldQuit())
433 snd_playSong(15);
434
435 sq.animCommand(16);
436 sq.printText(7, textColor2); // Thank you for coming so quickly
437 sq.animCommand(16);
438 sq.animCommand(17);
439 for (int i = 0; i < 3; i++)
440 sq.animCommand(16);
441 sq.fadeText();
442 sq.animCommand(16);
443
444 sq.loadScene(8, 2, true);
445 sq.update(2);
446 sq.animCommand(32);
447 sq.printText(8, textColor2); // I am troubled my friend
448 sq.animCommand(33);
449 sq.animCommand(33);
450 for (int i = 0; i < 4; i++)
451 sq.animCommand(32);
452 sq.fadeText();
453
454 sq.printText(9, textColor2); // Ancient evil stirs in the Temple Darkmoon
455 sq.animCommand(33);
456 sq.animCommand(_flags.platform == Common::kPlatformAmiga ? 41 : 43);
457 sq.animCommand(33);
458 for (int i = 0; i < 3; i++)
459 sq.animCommand(32);
460 sq.fadeText();
461
462 sq.printText(10, textColor2); // I fear for the safety of our city
463 for (int i = 0; i < 4; i++)
464 sq.animCommand(33);
465 sq.animCommand(32);
466 sq.animCommand(32);
467
468 sq.fadeText();
469 sq.loadScene(9, 2);
470
471 sq.waitForSongNotifier(6);
472
473 sq.update(2);
474 sq.animCommand(34);
475
476 sq.printText(11, textColor2); // I need your help
477 for (int i = 0; i < 3; i++)
478 sq.animCommand(34);
479 sq.animCommand(35);
480 for (int i = 0; i < 4; i++)
481 sq.animCommand(34);
482 sq.fadeText();
483
484 sq.loadScene(12, 2);
485 sq.update(2);
486 sq.loadScene(6, 2, true);
487 sq.animCommand(18);
488
489 sq.printText(12, textColor2); // Three nights ago I sent forth a scout
490 sq.animCommand(19);
491 sq.animCommand(20);
492 sq.animCommand(22);
493 sq.animCommand(19);
494 sq.animCommand(20);
495 sq.animCommand(18);
496 sq.fadeText();
497
498 sq.printText(13, textColor2); // She has not yet returned
499 sq.animCommand(20);
500 sq.animCommand(19);
501 sq.animCommand(23);
502 sq.animCommand(24);
503 sq.animCommand(20);
504 sq.animCommand(19);
505 sq.animCommand(17);
506 sq.animCommand(18);
507 sq.fadeText();
508
509 sq.printText(14, textColor2); // I fear for her safety
510 sq.animCommand(19);
511 sq.animCommand(20);
512 sq.animCommand(20);
513 sq.animCommand(18);
514 sq.animCommand(25);
515 sq.animCommand(18);
516 sq.animCommand(18);
517 sq.fadeText();
518 sq.animCommand(18);
519 sq.animCommand(18);
520
521 sq.printText(15, textColor2); // Take this coin
522 sq.animCommand(28);
523 sq.animCommand(19);
524 sq.animCommand(20);
525 sq.animCommand(18);
526 sq.animCommand(18);
527 sq.fadeText();
528
529 sq.loadScene(10, 2);
530
531 if (_flags.platform == Common::kPlatformAmiga)
532 _screen->fadeToBlack(10);
533
534 _screen->clearCurPage();
535 if (_flags.platform == Common::kPlatformAmiga)
536 sq.setPalette(0);
537 _screen->updateScreen();
538
539 sq.animCommand(37, 18);
540 sq.animCommand(36, 36);
541
542 sq.loadScene(12, 2);
543 _screen->clearCurPage();
544 sq.update(2);
545
546 sq.loadScene(11, 2, true);
547 sq.printText(16, textColor2); // I will use it to contact you
548 sq.animCommand(19);
549 sq.animCommand(20);
550 sq.animCommand(20);
551 sq.animCommand(18);
552 sq.animCommand(18);
553 sq.fadeText();
554
555 sq.printText(17, textColor2); // You must act quickly
556 sq.animCommand(19);
557 sq.animCommand(20);
558 sq.animCommand(19);
559 sq.animCommand(18);
560 sq.animCommand(18);
561 sq.fadeText();
562 sq.animCommand(18);
563
564 sq.printText(18, textColor2); // I will teleport you near Darkmoon
565 sq.animCommand(20);
566 sq.animCommand(27);
567 sq.animCommand(20);
568 sq.animCommand(19);
569 sq.animCommand(18);
570 sq.animCommand(18);
571 sq.fadeText();
572 sq.animCommand(18);
573
574 sq.printText(19, textColor2); // May luck be with you my friend
575 sq.animCommand(19);
576 sq.animCommand(19);
577 sq.animCommand(20);
578 sq.animCommand(18);
579 sq.fadeText();
580 sq.animCommand(29);
581
582 sq.waitForSongNotifier(7);
583
584 sq.animCommand(30);
585 sq.animCommand(31);
586
587 sq.waitForSongNotifier(8, true);
588
589 if (_flags.platform == Common::kPlatformAmiga && !skipFlag() && !shouldQuit()) {
590 static const uint8 magicHandsCol[] = { 0x15, 0x1D, 0x3A, 0x32, 0x32, 0x3F };
591 snd_fadeOut();
592 _screen->getPalette(0).copy(magicHandsCol, 0, 1, 31);
593 _screen->fadePalette(_screen->getPalette(0), 32);
594 _screen->getPalette(0).copy(magicHandsCol, 1, 1, 31);
595 _screen->fadePalette(_screen->getPalette(0), 32);
596 }
597
598 if (skipFlag() || shouldQuit())
599 snd_fadeOut();
600 else {
601 _screen->setScreenDim(17);
602 _screen->clearCurDim();
603 snd_playSoundEffect(14);
604
605 if (_configRenderMode != Common::kRenderEGA)
606 sq.fadePalette(10, 1);
607 _screen->setClearScreenDim(18);
608 sq.delay(6);
609 if (_configRenderMode != Common::kRenderEGA)
610 sq.fadePalette(9, 1);
611 _screen->clearCurPage();
612 }
613 sq.fadePalette(9, 10);
614 }
615
seq_playFinale()616 void DarkMoonEngine::seq_playFinale() {
617 _screen->fadeToBlack();
618 _screen->clearCurPage();
619 _screen->clearPage(2);
620
621 DarkmoonSequenceHelper sq(_system, this, _screen, DarkmoonSequenceHelper::kFinale);
622
623 _screen->setCurPage(0);
624
625 _sound->loadSoundFile(0);
626 snd_stopSound();
627 sq.delay(3);
628 _screen->updateScreen();
629
630 uint8 textColor1 = 10;
631 uint8 textColor2 = 15;
632
633 if (_flags.platform == Common::kPlatformAmiga) {
634 textColor1 = 29;
635 textColor2 = 31;
636 } else if (_configRenderMode == Common::kRenderEGA) {
637 textColor1 = 15;
638 }
639
640 sq.loadScene(0, 2);
641 sq.delay(18);
642
643 if (!skipFlag() && !shouldQuit() && _flags.platform != Common::kPlatformAmiga)
644 snd_playSong(1);
645 sq.update(2);
646
647 sq.loadScene(1, 2);
648
649 sq.animCommand(0);
650 sq.animCommand(0);
651 for (int i = 0; i < 3; i++)
652 sq.animCommand(2);
653 sq.animCommand(1);
654 sq.animCommand(2);
655 sq.animCommand(2);
656
657 sq.printText(0, textColor1); // Finally, Dran has been defeated
658 for (int i = 0; i < 7; i++)
659 sq.animCommand(2);
660 sq.fadeText();
661 sq.animCommand(2);
662
663 sq.waitForSongNotifier(1);
664
665 sq.printText(1, textColor1); // Suddenly, your friend Khelben appears
666 sq.animCommand(4);
667 for (int i = 0; i < 3; i++)
668 sq.animCommand(2);
669 sq.fadeText();
670
671 sq.printText(2, textColor2); // Greetings, my victorious friends
672 for (int i = 0; i < 4; i++)
673 sq.animCommand(5);
674 sq.animCommand(2);
675 sq.animCommand(2);
676 sq.fadeText();
677 sq.animCommand(6);
678
679 sq.printText(3, textColor2); // You have defeated Dran
680 for (int i = 0; i < 5; i++)
681 sq.animCommand(5);
682 sq.animCommand(2);
683 sq.animCommand(2);
684 sq.fadeText();
685
686 sq.printText(4, textColor2); // I did not know Dran was a dragon
687 for (int i = 0; i < 4; i++)
688 sq.animCommand(5);
689 sq.animCommand(2);
690 sq.animCommand(2);
691 sq.fadeText();
692
693 sq.printText(5, textColor2); // He must have been over 300 years old
694 for (int i = 0; i < 4; i++)
695 sq.animCommand(5);
696 sq.animCommand(2);
697 sq.animCommand(2);
698 sq.fadeText();
699
700 sq.printText(6, textColor2); // His power is gone
701 for (int i = 0; i < 3; i++)
702 sq.animCommand(5);
703 sq.animCommand(2);
704 sq.animCommand(2);
705 sq.fadeText();
706
707 sq.printText(7, textColor2); // But Darkmoon is still a source of great evil
708 for (int i = 0; i < 4; i++)
709 sq.animCommand(5);
710 sq.animCommand(2);
711 sq.animCommand(2);
712 sq.fadeText();
713
714 sq.printText(8, textColor2); // And many of his minions remain
715 for (int i = 0; i < 4; i++)
716 sq.animCommand(5);
717 sq.animCommand(2);
718 sq.animCommand(2);
719 sq.fadeText();
720
721 sq.loadScene(2, 2);
722 sq.update(2);
723 sq.loadScene(3, 2);
724 _screen->copyRegion(8, 8, 0, 0, 304, 128, 0, 2, Screen::CR_NO_P_CHECK);
725
726 sq.printText(9, textColor2); // Now we must leave this place
727 sq.animCommand(7);
728 sq.animCommand(8);
729 sq.animCommand(7);
730 sq.animCommand(7, 36);
731 sq.fadeText();
732
733 sq.printText(10, textColor2); // So my forces can destroy it..
734 for (int i = 0; i < 3; i++)
735 sq.animCommand(7);
736 sq.animCommand(8);
737 sq.animCommand(7);
738 sq.animCommand(7, 36);
739 sq.animCommand(8, 18);
740 sq.fadeText();
741
742 sq.printText(11, textColor2); // Follow me
743 sq.animCommand(7, 18);
744 sq.animCommand(9, 18);
745 sq.animCommand(8, 18);
746 sq.fadeText();
747
748 sq.loadScene(7, 2);
749
750 sq.copyPalette(3, 0);
751
752 sq.loadScene(4, 2);
753
754 sq.waitForSongNotifier(2);
755
756 _screen->clearCurPage();
757 sq.update(2);
758
759 sq.loadScene(8, 2);
760 sq.loadScene(6, 6);
761 sq.delay(10);
762
763 sq.printText(12, textColor1); // Powerful mages stand ready for the final assault...
764 sq.delay(90);
765 sq.fadeText();
766
767 sq.waitForSongNotifier(3);
768
769 if (!skipFlag() && !shouldQuit())
770 snd_playSoundEffect(7);
771 sq.delay(8);
772
773 sq.animCommand(10);
774 sq.animCommand(13);
775 if (_flags.platform != Common::kPlatformAmiga)
776 sq.initDelayedPaletteFade(4, 1);
777
778 sq.animCommand(14);
779 sq.animCommand(13);
780 sq.animCommand(14);
781 sq.animCommand(14);
782 sq.animCommand(13);
783 if (_flags.platform != Common::kPlatformAmiga)
784 sq.initDelayedPaletteFade(2, 1);
785
786 sq.animCommand(15);
787 sq.animCommand(14);
788 sq.animCommand(13);
789 sq.animCommand(15);
790 sq.animCommand(15);
791 sq.animCommand(11);
792
793 sq.printText(13, textColor1); // The temple's evil is very strong
794 sq.delay(72);
795 sq.fadeText();
796
797 sq.printText(14, textColor1); // It must not be allowed...
798 sq.delay(72);
799 sq.fadeText();
800
801 sq.waitForSongNotifier(4);
802
803 if (!skipFlag() && !shouldQuit())
804 snd_playSoundEffect(7);
805 sq.delay(8);
806
807 sq.animCommand(10);
808 if (_flags.platform != Common::kPlatformAmiga)
809 sq.initDelayedPaletteFade(5, 1);
810 sq.animCommand(13);
811 sq.animCommand(14);
812 sq.animCommand(13);
813 sq.animCommand(14);
814 sq.animCommand(13);
815 sq.animCommand(13);
816 sq.animCommand(14);
817 sq.animCommand(14);
818 sq.animCommand(13);
819 sq.animCommand(12);
820 if (_flags.platform == Common::kPlatformAmiga)
821 sq.fadePalette(2, 3);
822 for (int i = 0; i < 4; i++)
823 sq.animCommand(16);
824 if (_flags.platform == Common::kPlatformAmiga)
825 sq.fadePalette(4, 3);
826 sq.animCommand(17);
827 sq.animCommand(18);
828
829 sq.printText(15, textColor1); // The temple ceases to exist
830 if (_flags.platform != Common::kPlatformAmiga) {
831 sq.initDelayedPaletteFade(6, 1);
832 } else if (skipFlag()) {
833 _screen->fadeToBlack();
834 } else {
835 _screen->fadePalette(_screen->getPalette(5), 127);
836 sq.copyPalette(5, 0);
837 }
838 sq.delay(36);
839
840 if (!skipFlag() && !shouldQuit())
841 snd_playSoundEffect(11);
842
843 sq.delay(54);
844 sq.fadeText();
845 sq.loadScene(12, 2);
846
847 sq.waitForSongNotifier(5);
848
849 if (!skipFlag() && !shouldQuit())
850 snd_playSoundEffect(6);
851
852 if (_flags.platform == Common::kPlatformAmiga)
853 sq.copyPalette(6, 0);
854
855 if (!skipFlag() && !shouldQuit()) {
856 if (_configRenderMode != Common::kRenderEGA)
857 sq.setPaletteWithoutTextColor(0);
858 _screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
859 }
860 sq.delay(18);
861
862 sq.printText(16, textColor2); // My friends, our work is done
863 sq.animCommand(20);
864 sq.animCommand(19);
865 sq.animCommand(19, 36);
866 if (!skipFlag() && !shouldQuit())
867 snd_playSoundEffect(12);
868 sq.fadeText();
869
870 sq.printText(17, textColor2); // Thank you
871 sq.animCommand(19);
872 sq.animCommand(20, 36);
873 sq.fadeText();
874
875 sq.printText(18, textColor2); // You have earned my deepest respect
876 if (!skipFlag() && !shouldQuit())
877 snd_playSoundEffect(11);
878 sq.animCommand(20);
879 sq.animCommand(19);
880 sq.animCommand(19);
881 if (!skipFlag() && !shouldQuit())
882 snd_playSoundEffect(11);
883 sq.delay(36);
884 sq.fadeText();
885
886 sq.printText(19, textColor2); // We will remember you always
887 sq.animCommand(19);
888 sq.animCommand(19, 18);
889 if (!skipFlag() && !shouldQuit())
890 snd_playSoundEffect(11);
891 sq.animCommand(20, 18);
892 sq.fadeText();
893
894 sq.delay(28);
895 if (!skipFlag() && !shouldQuit())
896 snd_playSoundEffect(12);
897 sq.delay(3);
898
899 sq.loadScene(5, 2);
900 if (skipFlag() || shouldQuit()) {
901 _screen->copyRegion(0, 0, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
902 } else {
903 sq.updateAmigaSound();
904 snd_playSoundEffect(6);
905 if (_configRenderMode != Common::kRenderEGA)
906 sq.setPaletteWithoutTextColor(0);
907 _screen->crossFadeRegion(0, 0, 8, 8, 304, 128, 2, 0);
908 }
909
910 if (!skipFlag() && !shouldQuit())
911 snd_playSoundEffect(12);
912 sq.delay(5);
913 if (!skipFlag() && !shouldQuit())
914 snd_playSoundEffect(11);
915 sq.delay(11);
916 if (!skipFlag() && !shouldQuit())
917 snd_playSoundEffect(12);
918 sq.delay(7);
919 if (!skipFlag() && !shouldQuit())
920 snd_playSoundEffect(11);
921 sq.delay(12);
922 if (!skipFlag() && !shouldQuit())
923 snd_playSoundEffect(12);
924 sq.updateAmigaSound();
925
926 removeInputTop();
927 resetSkipFlag(true);
928
929 sq.loadScene(10, 2);
930 sq.loadScene(9, 2);
931
932 if (_flags.platform == Common::kPlatformAmiga) {
933 sq.setPalette(7);
934 sq.delay(3);
935 } else {
936 snd_stopSound();
937 sq.delay(3);
938 _sound->loadSoundFile(1);
939 }
940
941 sq.delay(18);
942 if (!skipFlag() && !shouldQuit() && _flags.platform != Common::kPlatformAmiga)
943 snd_playSong(_flags.platform == Common::kPlatformFMTowns ? 16 : 1);
944
945 int temp = 0;
946 const uint8 *creditsData = (_flags.platform != Common::kPlatformDOS) ? _res->fileData("CREDITS.TXT", 0) : _staticres->loadRawData(kEoB2CreditsData, temp);
947
948 seq_playCredits(&sq, creditsData, 18, 2, 6, 2);
949
950 if (_flags.platform != Common::kPlatformDOS)
951 delete[] creditsData;
952
953 sq.delay(90);
954
955 removeInputTop();
956 resetSkipFlag(true);
957
958 if (_configRenderMode != Common::kRenderEGA) {
959 if (_flags.platform != Common::kPlatformAmiga)
960 sq.setPalette(11);
961 sq.fadePalette(9, 10);
962 }
963
964 _screen->clearCurPage();
965 sq.loadScene(11, 2);
966
967 static const uint8 finPortraitPos[] = { 0x50, 0x50, 0xD0, 0x50, 0x50, 0x90, 0xD0, 0x90, 0x90, 0x50, 0x90, 0x90 };
968
969 for (int i = 0; i < 6; i++) {
970 if (!testCharacter(i, 1))
971 continue;
972 if (i > 3)
973 _screen->drawShape(2, sq._shapes[6 + i], finPortraitPos[i << 1] - 16, finPortraitPos[(i << 1) + 1] - 16, 0);
974 _screen->drawShape(2, _characters[i].faceShape, finPortraitPos[i << 1], finPortraitPos[(i << 1) + 1], 0);
975 }
976
977 _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
978
979 if (_flags.platform == Common::kPlatformFMTowns)
980 sq.copyPalette(12, 0);
981
982 if (_flags.platform != Common::kPlatformAmiga)
983 sq.setPalette(9);
984 sq.fadePalette(0, 18);
985
986 while (!skipFlag() && !shouldQuit()) {
987 sq.updateAmigaSound();
988 delay(_tickLength);
989 }
990
991 snd_stopSound();
992 removeInputTop();
993 resetSkipFlag(true);
994
995 sq.fadePalette(9, 10);
996 }
997
seq_playCredits(DarkmoonSequenceHelper * sq,const uint8 * data,int sd,int backupPage,int tempPage,int speed)998 void DarkMoonEngine::seq_playCredits(DarkmoonSequenceHelper *sq, const uint8 *data, int sd, int backupPage, int tempPage, int speed) {
999 if (!data)
1000 return;
1001
1002 _screen->setFont(Screen::FID_8_FNT);
1003 _screen->setScreenDim(sd);
1004
1005 const ScreenDim *dm = _screen->_curDim;
1006 const uint8 col1 = _flags.platform == Common::kPlatformAmiga ? 19 : 12;
1007 const uint8 col2 = _flags.platform == Common::kPlatformAmiga ? 29 : 240;
1008
1009 _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, 0, backupPage, Screen::CR_NO_P_CHECK);
1010
1011 struct CreditsDataItem {
1012 int16 x;
1013 int16 y;
1014 const void *data;
1015 char *str;
1016 uint8 crlf;
1017 uint8 size;
1018 uint8 dataType;
1019 } items[36];
1020 memset(items, 0, sizeof(items));
1021
1022 const char *pos = (const char *)data;
1023 uint32 end = _system->getMillis();
1024 uint32 cur = 0;
1025 int i = 0;
1026
1027 do {
1028 for (bool loop = true; loop;) {
1029 sq->processDelayedPaletteFade();
1030 cur = _system->getMillis();
1031 if (end <= cur)
1032 break;
1033 delay(MIN<uint32>(_tickLength, end - cur));
1034 }
1035
1036 end = _system->getMillis() + ((speed * _tickLength) >> 1);
1037
1038 for (; i < 35 && *pos; i++) {
1039 int16 nextY = i ? items[i].y + items[i].size + (items[i].size >> 2) : dm->h;
1040
1041 const char *posOld = pos;
1042 pos = strchr(pos, 0x0D);
1043 if (!pos)
1044 pos = strchr(posOld, 0x00);
1045
1046 items[i + 1].crlf = *pos++;
1047
1048 if (*posOld == 2) {
1049 const uint8 *shp = sq->_shapes[(*++posOld) - 1];
1050 items[i + 1].data = shp;
1051 items[i + 1].size = shp[1];
1052 items[i + 1].x = (dm->w - shp[2]) << 2;
1053 items[i + 1].dataType = 1;
1054 delete[] items[i + 1].str;
1055 items[i + 1].str = 0;
1056
1057 } else {
1058 if (*posOld == 1) {
1059 posOld++;
1060 items[i + 1].size = 6;
1061 } else {
1062 items[i + 1].size = _screen->getFontWidth();
1063 }
1064
1065 items[i + 1].dataType = 0;
1066
1067 int l = pos - posOld;
1068 if (items[i + 1].crlf != 0x0D)
1069 l++;
1070
1071 delete[] items[i + 1].str;
1072 items[i + 1].str = new char[l];
1073 memcpy(items[i + 1].str, posOld, l);
1074 items[i + 1].str[l - 1] = 0;
1075 items[i + 1].data = 0;
1076 items[i + 1].x = (((dm->w << 3) - (strlen(items[i + 1].str) * items[i + 1].size)) >> 1) + 1;
1077 }
1078
1079 items[i + 1].y = nextY;
1080 }
1081
1082 _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, backupPage, tempPage, Screen::CR_NO_P_CHECK);
1083 sq->updateAmigaSound();
1084
1085 for (int h = 0; h < i; h++) {
1086 if (items[h + 1].y < dm->h) {
1087 if (items[h + 1].dataType == 1) {
1088 _screen->drawShape(tempPage, (const uint8 *)items[h + 1].data, items[h + 1].x, items[h + 1].y, sd);
1089 } else {
1090 _screen->setCurPage(tempPage);
1091
1092 if (items[h + 1].size == 6)
1093 _screen->setFont(Screen::FID_6_FNT);
1094
1095 _screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x - 1, dm->sy + items[h + 1].y + 1, col1, 0);
1096 _screen->printText(items[h + 1].str, (dm->sx << 3) + items[h + 1].x, dm->sy + items[h + 1].y, col2, 0);
1097
1098 if (items[h + 1].size == 6)
1099 _screen->setFont(Screen::FID_8_FNT);
1100
1101 _screen->setCurPage(0);
1102 }
1103 }
1104
1105 items[h + 1].y -= MAX<int>(1, speed >> 1);
1106 }
1107
1108 _screen->copyRegion(dm->sx << 3, dm->sy, dm->sx << 3, dm->sy, dm->w << 3, dm->h, tempPage, 0, Screen::CR_NO_P_CHECK);
1109 _screen->updateScreen();
1110
1111 if (-items[1].size > items[1].y) {
1112 delete[] items[1].str;
1113 --i;
1114 for (int t = 1; t <= i; t++)
1115 memcpy(&items[t], &items[t + 1], sizeof(CreditsDataItem));
1116 items[i + 1].str = 0;
1117 }
1118
1119 if (i < 35 && ((items[i].y + items[i].size) < (dm->sy + dm->h))) {
1120 resetSkipFlag(true);
1121 break;
1122 }
1123
1124 sq->processDelayedPaletteFade();
1125 } while (!skipFlag() && i && !shouldQuit());
1126
1127 for (i = 0; i < 35; i++)
1128 delete[] items[i].str;
1129 }
1130
DarkmoonSequenceHelper(OSystem * system,DarkMoonEngine * vm,Screen_EoB * screen,DarkmoonSequenceHelper::Mode mode)1131 DarkmoonSequenceHelper::DarkmoonSequenceHelper(OSystem *system, DarkMoonEngine *vm, Screen_EoB *screen, DarkmoonSequenceHelper::Mode mode) : _system(system), _vm(vm), _screen(screen) {
1132 init(mode);
1133 }
1134
~DarkmoonSequenceHelper()1135 DarkmoonSequenceHelper::~DarkmoonSequenceHelper() {
1136 if (_vm->_flags.platform != Common::kPlatformAmiga) {
1137 for (int i = 4; _config->palFiles[i]; i++)
1138 delete _palettes[i];
1139 for (int i = 9; i < 13; ++i)
1140 delete _palettes[i];
1141 }
1142
1143 for (int i = 0; i < 7; i++)
1144 delete[] _fadingTables[i];
1145
1146 for (int i = 0; i < 54; i++)
1147 delete[] _shapes[i];
1148 delete[] _shapes;
1149
1150 delete[] _config->animData;
1151 delete[] _config->shapeDefs;
1152 delete[] _config->cpsData;
1153 delete _config;
1154
1155 _screen->enableHiColorMode(true);
1156 _screen->clearCurPage();
1157 _screen->setFont(_prevFont);
1158 _screen->updateScreen();
1159
1160 _system->delayMillis(150);
1161 _vm->resetSkipFlag(true);
1162 _vm->_allowSkip = false;
1163 }
1164
loadScene(int index,int pageNum,bool ignorePalette)1165 void DarkmoonSequenceHelper::loadScene(int index, int pageNum, bool ignorePalette) {
1166 Common::String file;
1167 Common::SeekableReadStream *s = 0;
1168 uint32 chunkID = 0;
1169 bool isRawData = false;
1170
1171 if (_config->cpsFiles) {
1172 file = _config->cpsFiles[index];
1173 s = _vm->resource()->createReadStream(file);
1174 }
1175
1176 if (s) {
1177 chunkID = s->readUint32LE();
1178 s->seek(0);
1179 }
1180
1181 if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
1182 // Tolerance for diffenrences up to 2 bytes is needed in some cases
1183 if ((((int32)(chunkID & 0xFFFF) + 5) & ~3) != (((s->size()) + 3) & ~3))
1184 isRawData = true;
1185 } else if (file.firstChar() == 'X' && _vm->gameFlags().lang == Common::DE_DEU) {
1186 isRawData = true;
1187 }
1188
1189 if (_config->cpsData[index]) {
1190 _screen->decodeSHP(_config->cpsData[index], pageNum);
1191 } else if (s && chunkID == MKTAG('F', 'O', 'R', 'M')) {
1192 // The original code also handles files with FORM chunks and ILBM and PBM sub chunks.
1193 // Up until now I haven't found any need for these (Amiga versions included).
1194 // We error out here theoretically, but this should never happen.
1195 error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d - unhandled FORM chunk encountered", index);
1196
1197 } else if (s && !isRawData) {
1198 delete s;
1199 _screen->loadBitmap(_config->cpsFiles[index], pageNum | 1, pageNum | 1, ignorePalette ? 0 : _palettes[0]);
1200
1201 } else if (s && _vm->gameFlags().platform == Common::kPlatformAmiga) {
1202 delete s;
1203 _screen->loadSpecialAmigaCPS(_config->cpsFiles[index], pageNum | 1, true);
1204
1205 } else {
1206 if (!s) {
1207 file.setChar('X', 0);
1208 s = _vm->resource()->createReadStream(file);
1209 }
1210
1211 if (!s)
1212 error("DarkmoonSequenceHelper::loadScene(): CPS file loading failure in scene %d", index);
1213
1214 if (_config->loadScenePal)
1215 s->read(_palettes[0]->getData(), 768);
1216 else
1217 s->seek(768);
1218 _screen->loadFileDataToPage(s, 3, 64000);
1219 delete s;
1220 }
1221
1222 int cp = _screen->setCurPage(pageNum);
1223
1224 if (_config->shapeDefs[index]) {
1225 for (const DarkMoonShapeDef *df = _config->shapeDefs[index]; df->w; df++) {
1226 uint16 shapeIndex = (df->index < 0) ? df->index * -1 : df->index;
1227 if (_shapes[shapeIndex])
1228 delete[] _shapes[shapeIndex];
1229 _shapes[shapeIndex] = _screen->encodeShape(df->x, df->y, df->w, df->h, (df->index >> 8) != 0);
1230 }
1231 }
1232
1233 _screen->setCurPage(cp);
1234
1235 if (_vm->_configRenderMode == Common::kRenderEGA)
1236 setPalette(0);
1237
1238 _screen->convertPage(pageNum | 1, pageNum, 0);
1239
1240 if ((pageNum == 0 || pageNum == 1) && !_vm->skipFlag() && !_vm->shouldQuit())
1241 _screen->updateScreen();
1242 }
1243
animCommand(int index,int del)1244 void DarkmoonSequenceHelper::animCommand(int index, int del) {
1245 if (_vm->skipFlag() || _vm->shouldQuit())
1246 return;
1247
1248 index += _platformAnimOffset;
1249 uint32 end = 0;
1250
1251 for (const DarkMoonAnimCommand *s = _config->animData[index]; s->command != 0xFF && !_vm->skipFlag() && !_vm->shouldQuit(); s++) {
1252 updateAmigaSound();
1253
1254 int palIndex = s->pal + _config->animPalOffs;
1255
1256 int x = s->x1;
1257 if (x >= Screen::SCREEN_W)
1258 x >>= 1;
1259 int y = s->y1;
1260 int x2 = 0;
1261 uint16 shapeW = 0;
1262 uint16 shapeH = 0;
1263
1264 switch (s->command) {
1265 case 0:
1266 // flash palette
1267 if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
1268 setPaletteWithoutTextColor(palIndex);
1269 delay(s->delay);
1270 if (_vm->_configRenderMode != Common::kRenderEGA && _config->animCmdRestorePal && s->pal)
1271 setPaletteWithoutTextColor(0);
1272 break;
1273
1274 case 1:
1275 // draw shape, then restore background
1276 shapeW = _shapes[s->obj][2];
1277 shapeH = _shapes[s->obj][3];
1278
1279 if (_config->animCmd1ShapeFrame == 18) {
1280 _screen->setScreenDim(18);
1281 x -= (_screen->_curDim->sx << 3);
1282 y -= _screen->_curDim->sy;
1283 if (x < 0)
1284 shapeW -= ((-x >> 3) + 1);
1285 else
1286 x2 = x;
1287 }
1288
1289 _screen->drawShape(0, _shapes[s->obj], x, y, _config->animCmd1ShapeFrame);
1290
1291 if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
1292 setPaletteWithoutTextColor(palIndex);
1293 else
1294 _screen->updateScreen();
1295
1296 delay(s->delay);
1297
1298 if (_config->animCmd1ShapeFrame == 0) {
1299 if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
1300 setPaletteWithoutTextColor(0);
1301 _screen->copyRegion(x - 8, y - 8, x, y, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
1302 } else {
1303 _screen->copyRegion(x2, y, x2 + (_screen->_curDim->sx << 3), y + _screen->_curDim->sy, (shapeW + 1) << 3, shapeH, 2, 0, Screen::CR_NO_P_CHECK);
1304 }
1305
1306 _screen->updateScreen();
1307 break;
1308
1309 case 2:
1310 // draw shape
1311 _screen->drawShape(_screen->_curPage, _shapes[s->obj], x, y, 0);
1312
1313 if (_vm->_configRenderMode != Common::kRenderEGA && s->pal)
1314 setPaletteWithoutTextColor(palIndex);
1315 else if (!_screen->_curPage)
1316 _screen->updateScreen();
1317
1318 delay(s->delay);
1319
1320 if (_vm->_configRenderMode != Common::kRenderEGA && _config->animCmdRestorePal && s->pal)
1321 setPaletteWithoutTextColor(0);
1322 break;
1323
1324 case 3:
1325 case 4:
1326 // fade shape in or out or restore background
1327 if (!_config->shpBackgroundFading)
1328 break;
1329
1330 if (_vm->_configRenderMode == Common::kRenderEGA) {
1331 if (palIndex)
1332 _screen->drawShape(0, _shapes[s->obj], s->x1, y, 0);
1333 else
1334 _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
1335 _screen->updateScreen();
1336 delay(s->delay /** 7*/);
1337 } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
1338 end = _system->getMillis() + s->delay * _vm->tickLength();
1339
1340 if (--palIndex) {
1341 uint8 obj = (palIndex - 1) * 10 + s->obj;
1342 _screen->copyRegion(s->x1 - 8, s->y1 - 8, 0, 0, (_shapes[obj][2] + 1) << 3, _shapes[obj][3], 2, 4, Screen::CR_NO_P_CHECK);
1343 _screen->drawShape(4, _shapes[obj], s->x1 & 7, 0, 0);
1344 _screen->copyRegion(0, 0, s->x1, s->y1, (_shapes[obj][2] + 1) << 3, _shapes[obj][3], 4, 0, Screen::CR_NO_P_CHECK);
1345 } else {
1346 _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
1347 }
1348 _screen->updateScreen();
1349
1350 _vm->delayUntil(end);
1351 } else {
1352 _screen->enableShapeBackgroundFading(true);
1353 _screen->setShapeFadingLevel(1);
1354
1355 end = _system->getMillis() + s->delay * _vm->tickLength();
1356
1357 if (palIndex) {
1358 _screen->setFadeTable(_fadingTables[palIndex - 1]);
1359
1360 _screen->copyRegion(s->x1 - 8, s->y1 - 8, 0, 0, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 4, Screen::CR_NO_P_CHECK);
1361 _screen->drawShape(4, _shapes[s->obj], s->x1 & 7, 0, 0);
1362 _screen->copyRegion(0, 0, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 4, 0, Screen::CR_NO_P_CHECK);
1363 } else {
1364 _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
1365 }
1366 _screen->updateScreen();
1367
1368 _vm->delayUntil(end);
1369 _screen->enableShapeBackgroundFading(false);
1370 _screen->setShapeFadingLevel(0);
1371 }
1372 break;
1373
1374 case 5:
1375 // copy region
1376 if (_config->animCmd5SetPal && s->pal)
1377 setPaletteWithoutTextColor(palIndex);
1378
1379 _screen->copyRegion(s->x2 << 3, s->y2, s->x1, s->y1, s->w << 3, s->h, s->obj ? _config->animCmd5AltPage : 2, 0, Screen::CR_NO_P_CHECK);
1380 _screen->updateScreen();
1381 delay(s->delay);
1382 break;
1383
1384 case 6:
1385 // play sound effect
1386 if (s->obj != 0xFF)
1387 _vm->snd_playSoundEffect(s->obj);
1388 break;
1389
1390 case 7:
1391 // restore background (only used in EGA mode)
1392 delay(s->delay);
1393 _screen->copyRegion(s->x1 - 8, s->y1 - 8, s->x1, s->y1, (_shapes[s->obj][2] + 1) << 3, _shapes[s->obj][3], 2, 0, Screen::CR_NO_P_CHECK);
1394 _screen->updateScreen();
1395 break;
1396
1397 default:
1398 error("DarkmoonSequenceHelper::animCommand(): Unknown animation opcode encountered.");
1399 break;
1400 }
1401 }
1402
1403 if (del > 0)
1404 delay(del);
1405 }
1406
setPlatformAnimIndexOffset(int offset)1407 void DarkmoonSequenceHelper::setPlatformAnimIndexOffset(int offset) {
1408 _platformAnimOffset = offset;
1409 }
1410
printText(int index,int color)1411 void DarkmoonSequenceHelper::printText(int index, int color) {
1412 if (_vm->skipFlag() || _vm->shouldQuit())
1413 return;
1414
1415 _screen->setClearScreenDim(17);
1416
1417 if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
1418 memset(_textColor, 58, 3);
1419 _palettes[0]->copy(_textColor, 0, 1, 31);
1420 color = 31;
1421 } else if (_vm->_configRenderMode != Common::kRenderEGA) {
1422 _palettes[0]->copy(*_palettes[0], color, 1, 255);
1423 setPalette(0);
1424 color = 255;
1425 }
1426
1427 char *temp = new char[strlen(_config->strings[index]) + 1];
1428 char *str = temp;
1429 strcpy(str, _config->strings[index]);
1430
1431 const ScreenDim *dm = _screen->_curDim;
1432 int fontHeight = _screen->getFontHeight() + 1;
1433
1434 for (int yOffs = 0; *str; yOffs += fontHeight) {
1435 char *cr = strchr(str, 13);
1436
1437 if (cr)
1438 *cr = 0;
1439
1440 uint32 len = strlen(str);
1441 _screen->printText(str, (dm->sx + ((dm->w - len) >> 1)) << 3, dm->sy + yOffs, color, dm->unkA);
1442
1443 if (cr) {
1444 *cr = 13;
1445 str = cr + 1;
1446 } else {
1447 str += len;
1448 }
1449 }
1450
1451 delete[] temp;
1452
1453 if (_vm->gameFlags().platform == Common::kPlatformAmiga)
1454 _screen->fadePalette(*_palettes[0], 20);
1455 else
1456 _screen->updateScreen();
1457 }
1458
fadeText()1459 void DarkmoonSequenceHelper::fadeText() {
1460 uint8 col = _vm->gameFlags().platform == Common::kPlatformAmiga ? 31 : 255;
1461
1462 if (_vm->skipFlag() || _vm->shouldQuit()) {
1463 _screen->clearCurDim();
1464 _screen->setPaletteIndex(col, 0, 0, 0);
1465 return;
1466 }
1467
1468 if (_vm->_configRenderMode != Common::kRenderEGA)
1469 _screen->fadeTextColor(_palettes[0], col, 8);
1470
1471 memset(_textColor, 0, 3);
1472 _screen->clearCurDim();
1473 }
1474
update(int srcPage)1475 void DarkmoonSequenceHelper::update(int srcPage) {
1476 if (_vm->skipFlag() || _vm->shouldQuit())
1477 return;
1478
1479 if (_vm->gameFlags().platform == Common::kPlatformAmiga)
1480 _screen->fadeToBlack(5);
1481
1482 _screen->copyRegion(0, 0, 8, 8, 304, 128, srcPage, 0, Screen::CR_NO_P_CHECK);
1483
1484 if (_vm->_configRenderMode != Common::kRenderEGA)
1485 setPaletteWithoutTextColor(0);
1486
1487 _screen->updateScreen();
1488 }
1489
init(DarkmoonSequenceHelper::Mode mode)1490 void DarkmoonSequenceHelper::init(DarkmoonSequenceHelper::Mode mode) {
1491 assert(mode == kIntro || mode == kFinale);
1492
1493 static const uint16 soundMarkersFMTowns[2][8] = {
1494 { 229, 447, 670, 1380, 2037, 3000, 4475, 4825 },
1495 { 475, 2030, 2200, 2752, 3475, 0, 0, 0 }
1496 };
1497
1498 int size = 0;
1499 _platformAnimOffset = 0;
1500 _sndNextTrack = 1;
1501 _sndNextTrackMarker = 0;
1502 _sndMarkersFMTowns = soundMarkersFMTowns[mode];
1503
1504 if (mode == kIntro) {
1505 _config = new Config(
1506 _vm->staticres()->loadStrings(kEoB2IntroStrings, size),
1507 _vm->staticres()->loadStrings(kEoB2IntroCPSFiles, size),
1508 new const uint8*[16],
1509 _vm->_flags.platform == Common::kPlatformAmiga ? 0 : (_vm->_configRenderMode == Common::kRenderEGA ? _palFilesIntroEGA : _palFilesIntroVGA),
1510 new const DarkMoonShapeDef*[16],
1511 new const DarkMoonAnimCommand *[44],
1512 false,
1513 false,
1514 true,
1515 true,
1516 _vm->_flags.platform == Common::kPlatformAmiga ? 1 : 0,
1517 0,
1518 false,
1519 2
1520 );
1521
1522 for (int i = 0; i < 44; i++)
1523 _config->animData[i] = _vm->staticres()->loadEoB2SeqData(kEoB2IntroAnimData00 + i, size);
1524
1525 for (int i = 0; i < 16; i++)
1526 _config->cpsData[i] = _vm->staticres()->loadRawData(kEoB2IntroCpsDataStreet1 + i, size);
1527
1528 memset(_config->shapeDefs, 0, 16 * sizeof(DarkMoonShapeDef*));
1529 _config->shapeDefs[0] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes00, size);
1530 _config->shapeDefs[1] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes01, size);
1531 _config->shapeDefs[4] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes04, size);
1532 _config->shapeDefs[7] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes07, size);
1533 _config->shapeDefs[13] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes13, size);
1534 _config->shapeDefs[14] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes14, size);
1535 _config->shapeDefs[15] = _vm->staticres()->loadEoB2ShapeData(kEoB2IntroShapes15, size);
1536
1537 } else {
1538 _config = new Config(
1539 _vm->staticres()->loadStrings(kEoB2FinaleStrings, size),
1540 _vm->staticres()->loadStrings(kEoB2FinaleCPSFiles, size),
1541 new const uint8*[13],
1542 _vm->_flags.platform == Common::kPlatformAmiga ? _palFilesFinaleAmiga : (_vm->_configRenderMode == Common::kRenderEGA ? _palFilesFinaleEGA : _palFilesFinaleVGA),
1543 new const DarkMoonShapeDef*[13],
1544 new const DarkMoonAnimCommand *[21],
1545 true,
1546 true,
1547 false,
1548 false,
1549 _vm->_flags.platform == Common::kPlatformAmiga ? 2 : 1,
1550 18,
1551 true,
1552 6
1553 );
1554
1555 for (int i = 0; i < 21; i++)
1556 _config->animData[i] = _vm->staticres()->loadEoB2SeqData(kEoB2FinaleAnimData00 + i, size);
1557
1558 for (int i = 0; i < 13; i++)
1559 _config->cpsData[i] = _vm->staticres()->loadRawData(kEoB2FinaleCpsDataDragon1 + i, size);
1560
1561 memset(_config->shapeDefs, 0, 13 * sizeof(DarkMoonShapeDef*));
1562 _config->shapeDefs[0] = _vm->staticres()->loadEoB2ShapeData(kEoB2FinaleShapes00, size);
1563 _config->shapeDefs[3] = _vm->staticres()->loadEoB2ShapeData(kEoB2FinaleShapes03, size);
1564 _config->shapeDefs[7] = _vm->staticres()->loadEoB2ShapeData(kEoB2FinaleShapes07, size);
1565 _config->shapeDefs[9] = _vm->staticres()->loadEoB2ShapeData(kEoB2FinaleShapes09, size);
1566 _config->shapeDefs[10] = _vm->staticres()->loadEoB2ShapeData(kEoB2FinaleShapes10, size);
1567 }
1568
1569 _screen->enableHiColorMode(false);
1570 _screen->disableDualPaletteMode();
1571 int numColors = 256;
1572
1573 if (_vm->_flags.platform == Common::kPlatformAmiga) {
1574 static const int8 palIndex[13] = { -1, -1, 3, 2, 4, 5, 6, 7, -1, -1, -1, -1, -1 };
1575 for (int i = 0; i < 13; ++i)
1576 _palettes[i] = &_screen->getPalette(i);
1577 Common::SeekableReadStream *s = _config->palFiles ? _vm->resource()->createReadStream(_config->palFiles[0]) : 0;
1578 numColors = 32;
1579 for (int i = 0; i < 13; ++i) {
1580 if (s && palIndex[i] != -1)
1581 _palettes[palIndex[i]]->loadAmigaPalette(*s, 0, 32);
1582 }
1583 delete s;
1584 } else {
1585 for (int i = 0; _config->palFiles[i]; i++) {
1586 if (i < 4)
1587 _palettes[i] = &_screen->getPalette(i);
1588 else
1589 _palettes[i] = new Palette(256);
1590 _screen->loadPalette(_config->palFiles[i], *_palettes[i]);
1591 }
1592
1593 for (int i = 9; i < 13; ++i)
1594 _palettes[i] = new Palette(256);
1595 }
1596
1597 _palettes[9]->fill(0, numColors, 0);
1598 _palettes[10]->fill(0, numColors, 63);
1599 _palettes[11]->fill(0, numColors, 0);
1600
1601
1602 if (_vm->gameFlags().platform == Common::kPlatformFMTowns)
1603 _screen->loadPalette("PALETTE.COL", *_palettes[12]);
1604
1605 for (int i = 0; i < 7; i++)
1606 _fadingTables[i] = 0;
1607
1608 uint8 *fadeData = (_vm->_configRenderMode != Common::kRenderCGA && _vm->_configRenderMode != Common::kRenderEGA) ? _vm->resource()->fileData("FADING.DAT", 0) : 0;
1609
1610 if (fadeData) {
1611 for (int i = 0; i < 7; i++) {
1612 _fadingTables[i] = new uint8[256];
1613 memcpy(_fadingTables[i], fadeData + (i << 8), 256);
1614 }
1615 } else {
1616 if (_vm->_flags.platform != Common::kPlatformAmiga && _vm->_configRenderMode != Common::kRenderCGA && _vm->_configRenderMode != Common::kRenderEGA) {
1617 uint8 *pal = _vm->resource()->fileData("PALETTE1.PAL", 0);
1618 for (int i = 0; i < 7; i++)
1619 _screen->createFadeTable(pal, _fadingTables[i], 18, (i + 1) * 36);
1620 delete[] pal;
1621 }
1622 }
1623
1624 delete[] fadeData;
1625
1626 _shapes = new const uint8*[54];
1627 memset(_shapes, 0, 54 * sizeof(uint8*));
1628
1629 _fadePalTimer = 0;
1630 _fadePalRate = 0;
1631
1632 memset(_textColor, 0, 3);
1633
1634 _screen->setScreenPalette(*_palettes[0]);
1635 _prevFont = _screen->setFont(_vm->gameFlags().platform == Common::kPlatformFMTowns ? Screen::FID_SJIS_LARGE_FNT : Screen::FID_8_FNT);
1636 _screen->hideMouse();
1637
1638 _vm->delay(150);
1639 _vm->_eventList.clear();
1640 _vm->_allowSkip = true;
1641 }
1642
setPaletteWithoutTextColor(int index)1643 void DarkmoonSequenceHelper::setPaletteWithoutTextColor(int index) {
1644 if (_vm->_configRenderMode == Common::kRenderEGA || _vm->skipFlag() || _vm->shouldQuit())
1645 return;
1646
1647 int numCol = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 31 : 255;
1648
1649 if (_vm->gameFlags().platform != Common::kPlatformAmiga) {
1650 if (!memcmp(_palettes[11]->getData(), _palettes[index]->getData(), numCol * 3))
1651 return;
1652 }
1653
1654 _palettes[11]->copy(*_palettes[index], 0, numCol);
1655 if (_vm->gameFlags().platform == Common::kPlatformAmiga)
1656 _palettes[11]->copy(_textColor, 0, 1, numCol);
1657 else
1658 _palettes[11]->copy(*_palettes[0], numCol, 1, numCol);
1659 setPalette(11);
1660
1661 _screen->updateScreen();
1662 _system->delayMillis(10);
1663 }
1664
setPalette(int index)1665 void DarkmoonSequenceHelper::setPalette(int index) {
1666 _screen->setScreenPalette(*_palettes[index]);
1667 }
1668
fadePalette(int index,int del)1669 void DarkmoonSequenceHelper::fadePalette(int index, int del) {
1670 if (_vm->skipFlag() || _vm->shouldQuit())
1671 return;
1672 if (_vm->_configRenderMode == Common::kRenderEGA) {
1673 setPalette(index);
1674 _screen->updateScreen();
1675 } else {
1676 _screen->fadePalette(*_palettes[index], del * _vm->tickLength());
1677 }
1678 }
1679
copyPalette(int srcIndex,int destIndex)1680 void DarkmoonSequenceHelper::copyPalette(int srcIndex, int destIndex) {
1681 _palettes[destIndex]->copy(*_palettes[srcIndex]);
1682 }
1683
initDelayedPaletteFade(int palIndex,int rate)1684 void DarkmoonSequenceHelper::initDelayedPaletteFade(int palIndex, int rate) {
1685 _palettes[11]->copy(*_palettes[0]);
1686
1687 _fadePalIndex = palIndex;
1688 _fadePalRate = rate;
1689 _fadePalTimer = _system->getMillis() + 2 * _vm->_tickLength;
1690 }
1691
processDelayedPaletteFade()1692 bool DarkmoonSequenceHelper::processDelayedPaletteFade() {
1693 if (_vm->skipFlag() || _vm->shouldQuit())
1694 return true;
1695
1696 if (_vm->_configRenderMode == Common::kRenderEGA || !_fadePalRate || (_system->getMillis() <= _fadePalTimer))
1697 return false;
1698
1699 if (_screen->delayedFadePalStep(_palettes[_fadePalIndex], _palettes[0], _fadePalRate)) {
1700 setPaletteWithoutTextColor(0);
1701 _fadePalTimer = _system->getMillis() + 3 * _vm->_tickLength;
1702 } else {
1703 _fadePalRate = 0;
1704 }
1705
1706 return false;
1707 }
1708
delay(uint32 ticks)1709 void DarkmoonSequenceHelper::delay(uint32 ticks) {
1710 if (_vm->skipFlag() || _vm->shouldQuit())
1711 return;
1712
1713 uint32 end = _system->getMillis() + ticks * _vm->_tickLength;
1714
1715 if (_config->palFading) {
1716 do {
1717 if (processDelayedPaletteFade())
1718 break;
1719 _vm->updateInput();
1720 } while (end > _system->getMillis());
1721 processDelayedPaletteFade();
1722
1723 } else {
1724 _vm->delayUntil(end);
1725 }
1726 }
1727
waitForSongNotifier(int index,bool introUpdateAnim)1728 void DarkmoonSequenceHelper::waitForSongNotifier(int index, bool introUpdateAnim) {
1729 if (_vm->gameFlags().platform == Common::kPlatformFMTowns)
1730 index = _sndMarkersFMTowns[index - 1];
1731 else if (_vm->sound()->getMusicType() != Sound::kAdLib)
1732 return;
1733
1734 int seq = 0;
1735
1736 while (_vm->sound()->musicEnabled() && _vm->sound()->checkTrigger() < index && !(_vm->skipFlag() || _vm->shouldQuit())) {
1737 if (introUpdateAnim) {
1738 animCommand(30 | seq);
1739 seq ^= 1;
1740 }
1741
1742 if (_config->palFading)
1743 processDelayedPaletteFade();
1744
1745 _vm->updateInput();
1746 }
1747 }
1748
updateAmigaSound()1749 void DarkmoonSequenceHelper::updateAmigaSound() {
1750 if (_vm->gameFlags().platform != Common::kPlatformAmiga || !_vm->sound()->musicEnabled())
1751 return;
1752
1753 int ct = _vm->sound()->checkTrigger();
1754 if (ct < _sndNextTrackMarker)
1755 return;
1756
1757 _vm->snd_playSong(_sndNextTrack++);
1758 if (_sndNextTrack == 4)
1759 _sndNextTrack = 1;
1760
1761 static const uint16 interval[4] = { 0, 1015, 4461, 1770 };
1762 _sndNextTrackMarker = interval[_sndNextTrack];
1763 }
1764
1765 const char *const DarkmoonSequenceHelper::_palFilesIntroVGA[] = {
1766 "PALETTE1.PAL",
1767 "PALETTE3.PAL",
1768 "PALETTE2.PAL",
1769 "PALETTE4.PAL",
1770 0
1771 };
1772
1773 const char *const DarkmoonSequenceHelper::_palFilesIntroEGA[] = {
1774 "PALETTE0.PAL",
1775 "PALETTE3.PAL",
1776 "PALETTE2.PAL",
1777 "PALETTE4.PAL",
1778 0
1779 };
1780
1781 const char *const DarkmoonSequenceHelper::_palFilesFinaleVGA[] = {
1782 "FINALE_0.PAL",
1783 "FINALE_0.PAL",
1784 "FINALE_1.PAL",
1785 "FINALE_2.PAL",
1786 "FINALE_3.PAL",
1787 "FINALE_4.PAL",
1788 "FINALE_5.PAL",
1789 "FINALE_6.PAL",
1790 "FINALE_7.PAL",
1791 0
1792 };
1793
1794 const char *const DarkmoonSequenceHelper::_palFilesFinaleEGA[] = {
1795 "FINALE_6.PAL",
1796 "FINALE_0.PAL",
1797 "FINALE_1.PAL",
1798 "FINALE_7.PAL",
1799 "FINALE_3.PAL",
1800 "FINALE_4.PAL",
1801 "FINALE_5.PAL",
1802 "FINALE_0.PAL",
1803 "FINALE_0.PAL",
1804 0
1805 };
1806
1807 const char *const DarkmoonSequenceHelper::_palFilesFinaleAmiga[] = {
1808 "FINALE.PAL",
1809 0
1810 };
1811
seq_nightmare()1812 void DarkMoonEngine::seq_nightmare() {
1813 Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
1814 _screen->clearCurDimOvl(0);
1815 _screen->copyRegion(0, 0, 0, 120, 176, 24, 12, 2, Screen::CR_NO_P_CHECK);
1816 initDialogueSequence();
1817 gui_drawDialogueBox();
1818
1819 _txt->printDialogueText(99, 0);
1820 snd_playSoundEffect(54);
1821
1822 static const uint8 seqX[] = { 0, 20, 0, 20 };
1823 static const uint8 seqY[] = { 0, 0, 96, 96 };
1824 static const uint8 seqDelay[] = { 12, 7, 7, 12 };
1825
1826 for (const int8 *i = _dreamSteps; *i != -1; ++i) {
1827 drawSequenceBitmap("DREAM", 0, seqX[*i], seqY[*i], 0);
1828 delay(seqDelay[*i] * _tickLength);
1829 }
1830
1831 _txt->printDialogueText(20, _okStrings[0]);
1832
1833 restoreAfterDialogueSequence();
1834
1835 _screen->setFont(of);
1836 }
1837
seq_kheldran()1838 void DarkMoonEngine::seq_kheldran() {
1839 Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
1840
1841 initDialogueSequence();
1842 gui_drawDialogueBox();
1843
1844 static const char file[] = "KHELDRAN";
1845 _screen->set16bitShadingLevel(4);
1846 _txt->printDialogueText(_kheldranStrings[0]);
1847 drawSequenceBitmap(file, 0, 0, 0, 0);
1848 _txt->printDialogueText(20, _moreStrings[0]);
1849 snd_playSoundEffect(56);
1850 drawSequenceBitmap(file, 0, 20, 0, 0);
1851 delay(10 * _tickLength);
1852 drawSequenceBitmap(file, 0, 0, 96, 0);
1853 delay(10 * _tickLength);
1854 drawSequenceBitmap(file, 0, 20, 96, 0);
1855 delay(7 * _tickLength);
1856 _txt->printDialogueText(76, _okStrings[0]);
1857
1858 restoreAfterDialogueSequence();
1859
1860 _screen->setFont(of);
1861 }
1862
seq_dranDragonTransformation()1863 void DarkMoonEngine::seq_dranDragonTransformation() {
1864 Screen::FontId of = _screen->setFont(Screen::FID_6_FNT);
1865
1866 initDialogueSequence();
1867 gui_drawDialogueBox();
1868
1869 static const char file[] = "DRANX";
1870 drawSequenceBitmap(file, 0, 0, 0, 0);
1871 _txt->printDialogueText(120, _moreStrings[0]);
1872 snd_playSoundEffect(56);
1873 drawSequenceBitmap(file, 0, 20, 0, 0);
1874 delay(7 * _tickLength);
1875 drawSequenceBitmap(file, 0, 0, 96, 0);
1876 delay(7 * _tickLength);
1877 drawSequenceBitmap(file, 0, 20, 96, 0);
1878 delay(18 * _tickLength);
1879
1880 restoreAfterDialogueSequence();
1881
1882 _screen->setFont(of);
1883 }
1884
1885 } // End of namespace Kyra
1886
1887 #endif // ENABLE_EOB
1888