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 #include "xeen/worldofxeen/clouds_cutscenes.h"
24 #include "xeen/sound.h"
25
26 namespace Xeen {
27 namespace WorldOfXeen {
28
29 #define WAIT(TIME) if (_subtitles.wait(TIME)) return false
30 #define ROTATE_BG screen.horizMerge(_mergeX); \
31 _mergeX = (_mergeX + 1) % SCREEN_WIDTH
32 #define LOAD_VORTEX loadScreen(Common::String::format("vort%02u.frm", cloudsCtr)); \
33 if (++cloudsCtr > 20) \
34 cloudsCtr = 1
35
showCloudsIntro()36 bool CloudsCutscenes::showCloudsIntro() {
37 EventsManager &events = *g_vm->_events;
38 FileManager &files = *g_vm->_files;
39 Screen &screen = *g_vm->_screen;
40 Sound &sound = *g_vm->_sound;
41
42 bool darkCc = files._ccNum;
43 files.setGameCc(0);
44 sound._musicSide = 0;
45 _subtitles.reset();
46
47 bool seenIntro = showCloudsTitle() && showCloudsIntroInner();
48
49 events.clearEvents();
50
51 // Roll up the scroll again
52 sound.songCommand(50);
53 doScroll(true, false);
54
55 sound.stopAllAudio();
56 screen.freePages();
57 files.setGameCc(darkCc ? 1 : 0);
58
59 return seenIntro;
60 }
61
showCloudsTitle()62 bool CloudsCutscenes::showCloudsTitle() {
63 Screen &screen = *_vm->_screen;
64 Sound &sound = *_vm->_sound;
65
66 // Initial logo display
67 screen.loadPalette("intro1.pal");
68 screen.loadBackground("logobak.raw");
69 screen.saveBackground();
70 screen.update();
71 screen.fadeIn(128);
72
73 SpriteResource logo[2] = {
74 SpriteResource("logo.vga"), SpriteResource("logo1.vga")
75 };
76 sound.playFX(1);
77
78 for (int idx = 0; idx < 80; ++idx) {
79 screen.restoreBackground();
80 logo[idx / 65].draw(0, idx % 65);
81 screen.update();
82
83 switch (idx) {
84 case 37:
85 sound.playFX(0);
86 sound.playFX(53);
87 sound.playSound("fire.voc");
88 break;
89 case 52:
90 case 60:
91 sound.playFX(3);
92 break;
93 case 64:
94 sound.playFX(2);
95 break;
96 case 66:
97 sound.playFX(52);
98 sound.playSound("meangro&.voc");
99 break;
100 default:
101 break;
102 }
103
104 WAIT(2);
105 }
106
107 screen.restoreBackground();
108 screen.update();
109 WAIT(30);
110
111 screen.fadeOut(8);
112 logo[0].clear();
113 logo[1].clear();
114
115 return true;
116 }
117
showCloudsIntroInner()118 bool CloudsCutscenes::showCloudsIntroInner() {
119 EventsManager &events = *_vm->_events;
120 Screen &screen = *_vm->_screen;
121 Sound &sound = *_vm->_sound;
122 Windows &windows = *_vm->_windows;
123
124 SpriteResource stars("stars.vga"), intro1("intro1.vga"),
125 lake("lake.vga"), xeen("xeen.vga"), wizTower("wiztower.vga"),
126 wizTower2("wiztwer2.vga"), lake2("lake2.vga"), lake3("lake3.vga"),
127 xeen1("xeen1.vga");
128
129 // Show the production splash screen
130 sound.playSong("mm4theme.m");
131 screen.loadBackground("jvc.raw");
132 screen.loadPalette("mm4.pal");
133 screen.update();
134 screen.fadeIn();
135 WAIT(30);
136 screen.fadeOut(8);
137
138 // Clouds of Xeen title with vertically scrolling background
139 screen.loadPalette("intro.pal");
140 screen.loadBackground("blank.raw");
141 screen.saveBackground();
142 stars.draw(0, 0);
143 stars.draw(0, 1, Common::Point(160, 0));
144 screen.loadPage(0);
145 intro1.draw(0, 0);
146 screen.loadPage(1);
147
148 bool fadeFlag = true;
149 for (int yCtr = SCREEN_HEIGHT, yScroll = 0, xeenCtr = -1; yCtr > 0; --yCtr, ++yScroll) {
150 screen.vertMerge(yScroll);
151 if (yCtr < 160) {
152 xeen.draw(0, 0);
153 }
154 if (yCtr < 100) {
155 xeen.draw(0, 0);
156 if (++xeenCtr < 14)
157 xeen1.draw(0, xeenCtr);
158 }
159 screen.update();
160
161 if (fadeFlag) {
162 screen.fadeIn();
163 fadeFlag = false;
164 }
165
166 WAIT(1);
167 }
168
169 // Remainder of vertical scrolling of background
170 screen.restoreBackground();
171 intro1.draw(0, 0);
172 screen.loadPage(0);
173 lake.draw(0, 0);
174 screen.loadPage(1);
175
176 bool drawFlag = false;
177 for (int yCtr = SCREEN_HEIGHT - 1, yScroll = 1, lakeCtr = 0; yCtr > 0; --yCtr, ++yScroll) {
178 screen.vertMerge(yScroll);
179
180 if (yCtr < 95) {
181 if (++lakeCtr >= 44 || drawFlag) {
182 lakeCtr = 0;
183 drawFlag = true;
184 } else {
185 lake3.draw(0, lakeCtr, Common::Point(0, yCtr));
186 }
187 }
188
189 xeen.draw(0, 0);
190 screen.update();
191 WAIT(1);
192 }
193
194 screen.freePages();
195
196 // Flying creatures moving horizontally
197 lake.draw(0, 0);
198 screen.saveBackground();
199
200 int frameNum = 0;
201 events.updateGameCounter();
202 for (int idx = 0; idx < 100; ++idx) {
203 frameNum = (frameNum + 1) % 43;
204 screen.restoreBackground();
205 lake2.draw(0, frameNum, Common::Point(0, 0), SPRFLAG_800);
206 WAIT(1);
207 }
208
209 // Zoom in on a closeup of the wizardry tower
210 const int XLIST1[16] = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 44, 48, 52, 56, 60, 64, 68 };
211 const int XLIST2[16] = { 160, 155, 150, 145, 140, 135, 130, 125, 120, 114, 108, 102, 96, 90, 84, 78 };
212 const int YLIST[23] = { 0, 6, 12, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50, 51 };
213
214 for (int idx = 15; idx >= 0; --idx) {
215 events.updateGameCounter();
216
217 screen.restoreBackground();
218 lake2.draw(0, frameNum, Common::Point(0, 0), SPRFLAG_800);
219 frameNum = (frameNum + 1) % 43;
220 wizTower.draw(0, 0, Common::Point(XLIST1[idx], YLIST[idx]), 0, idx);
221 wizTower.draw(0, 1, Common::Point(XLIST2[idx], YLIST[idx]), 0, idx);
222 screen.update();
223 WAIT(1);
224 }
225
226 // Cloaked figure walks horizontally
227 wizTower.draw(0, 0);
228 wizTower.draw(0, 1, Common::Point(160, 0));
229 screen.saveBackground();
230
231 for (int idx = 0; idx < 39; ++idx) {
232 screen.restoreBackground();
233 wizTower2.draw(0, idx);
234 screen.update();
235
236 WAIT(2);
237 }
238
239 screen.fadeOut();
240 lake2.clear();
241 lake3.clear();
242 xeen1.clear();
243
244 // All the lines whilst the scroll is open
245 SpriteResource groupo("groupo.vga"), group("group.vga"),
246 crodo("crodo.vga"), box("box.vga");
247
248 groupo.draw(0, 0);
249 groupo.draw(0, 1, Common::Point(160, 0));
250 crodo.draw(0, 0, Common::Point(0, -5));
251 windows[0].writeString(Res.CLOUDS_INTRO1);
252
253 // Unroll a scroll
254 if (doScroll(false, true))
255 return false;
256
257 sound.setMusicPercent(60);
258 screen.restoreBackground();
259 screen.update();
260 _subtitles.setLine(0);
261
262 // Loop through each spoken line
263 int ctr1 = 0, ctr2 = 0, ctr3 = 0, ctr4 = 0, ctr5 = 0, totalCtr = 0;
264 for (int lineCtr = 0; lineCtr < 14; ++lineCtr) {
265 if (lineCtr != 6 && lineCtr != 7) {
266 // Set subtitle to display (presuming subtitles are turned on)
267 switch (lineCtr) {
268 case 0:
269 _subtitles.setLine(0);
270 break;
271 case 1:
272 _subtitles.setLine(1);
273 break;
274 case 5:
275 _subtitles.setLine(2);
276 break;
277 case 11:
278 _subtitles.setLine(3);
279 break;
280 default:
281 break;
282 }
283
284 // Play the next sample
285 sound.playVoice(_INTRO_VOCS[lineCtr]);
286 }
287
288 events.timeMark1();
289 for (int frameCtr = 0, lookup = 0; sound.isSoundPlaying() ||
290 (_subtitles.active() && (lineCtr == 0 || lineCtr == 4 || lineCtr == 10 || lineCtr == 13)); ) {
291 groupo.draw(0, 0);
292 groupo.draw(0, 1, Common::Point(160, 0));
293
294 switch (lineCtr) {
295 case 2:
296 ctr1 = (ctr1 + 1) % 5;
297 group.draw(0, ctr1);
298 ctr4 = (ctr4 + 1) % 9;
299 break;
300
301 case 4:
302 ctr4 = (ctr4 + 1) % 9 + 9;
303 break;
304
305 case 8:
306 case 12:
307 ctr2 = (ctr2 + 1) % 3;
308 ctr4 = (ctr4 + 1) % 9;
309 ctr3 = (ctr3 + 1) % 6 + 3;
310 break;
311
312 case 9:
313 case 13:
314 ctr3 = (ctr3 + 1) % 3;
315 group.draw(0, ctr3 + 43, Common::Point(178, 134));
316 ctr4 = (ctr4 + 1) % 9;
317 ctr2 = (ctr2 % 15) + 3;
318 break;
319
320 default:
321 ctr4 = (ctr4 + 1) % 9;
322 ctr2 = (ctr2 + 1) % 15 + 3;
323 ctr3 = (ctr3 + 1) % 6 + 3;
324 break;
325 }
326
327 group.draw(0, ctr4 + 5, Common::Point(0, 99));
328 group.draw(0, ctr2 + 24, Common::Point(202, 12));
329 if ((++totalCtr % 30) == 0)
330 group.draw(0, 43, Common::Point(178, 134));
331
332 switch (lineCtr) {
333 case 2:
334 case 4:
335 case 8:
336 case 9:
337 case 12:
338 case 13: {
339 crodo.draw(0, 0, Common::Point(0, -5));
340 windows[0].writeString(Res.CLOUDS_INTRO1);
341
342 ctr5 = (ctr5 + 1) % 19;
343
344 WAIT(1);
345 continue;
346 }
347
348 default:
349 crodo.draw(0, frameCtr, Common::Point(0, -5));
350 if (lookup > 30)
351 lookup = 30;
352 frameCtr = _INTRO_FRAMES_VALS[_INTRO_FRAMES_LOOKUP[lineCtr]][lookup];
353 windows[0].writeString(Res.CLOUDS_INTRO1);
354
355 ctr5 = (ctr5 + 1) % 19;
356 break;
357 }
358
359 uint expiry = _INTRO_FRAMES_WAIT[_INTRO_FRAMES_LOOKUP[lineCtr]][lookup];
360 do {
361 WAIT(1);
362 } while (events.timeElapsed1() < expiry);
363
364 ++lookup;
365 if (!sound._fxOn && lookup > 30)
366 lookup = 0;
367 }
368
369 if (!sound._fxOn)
370 lineCtr = 20;
371
372 if (lineCtr == 5)
373 sound.playVoice(_INTRO_VOCS[6]);
374 else if (lineCtr == 6)
375 sound.playVoice(_INTRO_VOCS[7]);
376 }
377
378 return true;
379 }
380
showCloudsEnding(uint finalScore)381 void CloudsCutscenes::showCloudsEnding(uint finalScore) {
382 EventsManager &events = *g_vm->_events;
383 FileManager &files = *g_vm->_files;
384 Sound &sound = *g_vm->_sound;
385
386 bool darkCc = files._ccNum;
387 files.setGameCc(0);
388 _subtitles.reset();
389
390 _mirror.load("mirror.end");
391 _mirrBack.load("mirrback.end");
392 _mergeX = 0;
393 doScroll(true, false);
394
395 if (showCloudsEnding1())
396 if (showCloudsEnding2())
397 if (showCloudsEnding3())
398 if (showCloudsEnding4(finalScore))
399 showCloudsEnding5();
400
401 events.clearEvents();
402 sound.stopAllAudio();
403 files.setGameCc(darkCc ? 1 : 0);
404
405 if (!g_vm->shouldExit())
406 doScroll(true, false);
407 }
408
showCloudsEnding1()409 bool CloudsCutscenes::showCloudsEnding1() {
410 FileManager &files = *_vm->_files;
411 Screen &screen = *_vm->_screen;
412 Sound &sound = *_vm->_sound;
413
414 files._ccNum = false;
415 files.setGameCc(0);
416
417 // Show the castle with swirling clouds and lightning
418 SpriteResource prec;
419 prec.load("prec.end");
420 screen.loadBackground("blank.raw");
421 screen.loadPalette("mm4e.pal");
422
423 loadScreen(Common::String::format("prec00%02u.frm", 1));
424 prec.draw(0, 0);
425 prec.draw(0, 1, Common::Point(160, 0));
426 screen.fadeIn();
427 WAIT(15);
428
429 sound.playFX(1);
430 sound.playFX(34);
431
432 // Initial animation of vortex & lightning in the sky
433 for (int idx = 1; idx < 42; ++idx) {
434 // Load up the background frame of swirling clouds
435 loadScreen(Common::String::format("prec00%02u.frm", idx));
436
437 // Render castle in front of it
438 prec.draw(0, 0, Common::Point(0, 0));
439 prec.draw(0, 1, Common::Point(160, 0));
440 screen.update();
441
442 switch (idx) {
443 case 8:
444 case 18:
445 case 21:
446 sound.playFX(33);
447 break;
448
449 case 19:
450 case 25:
451 sound.playFX(34);
452 break;
453
454 default:
455 break;
456 }
457
458 WAIT(3);
459 }
460
461 prec.clear();
462
463 SpriteResource cast1[7], cast2[7], darkLord[3];
464 for (int idx = 1; idx < 7; ++idx)
465 cast1[idx - 1].load(Common::String::format("cast%02d.end", idx));
466 for (int idx = 1; idx < 7; ++idx)
467 cast2[idx - 1].load(Common::String::format("casb%02d.end", idx));
468 for (int idx = 1; idx < 4; ++idx)
469 darkLord[idx - 1].load(Common::String::format("darklrd%d.end", idx));
470
471 // Castle close-up
472 int cloudsCtr = 1;
473 for (int idx = 1; idx < 16; ++idx) {
474 LOAD_VORTEX;
475 cast1[0].draw(0, 0);
476 cast2[0].draw(0, 0, Common::Point(0, 100));
477 WAIT(3);
478 }
479
480 screen.loadPalette("mm4.pal");
481 screen.fadeIn(0x81);
482
483 // Castle gets destroyed / sucked into the vortex
484 const byte COUNTS1[6] = { 9, 3, 2, 2, 3, 15 };
485 bool flag = false;
486 for (int idx1 = 1; idx1 < 7; ++idx1) {
487 for (int idx2 = 0; idx2 < COUNTS1[idx1 - 1]; ++idx2) {
488 if (flag && !sound.isSoundPlaying()) {
489 flag = false;
490 sound.playFX(34);
491 } else if (!flag && idx1 == 1 && idx2 == 6) {
492 flag = true;
493 sound.playVoice("xeenlaff.voc");
494 }
495
496 switch (cloudsCtr) {
497 case 0:
498 case 1:
499 case 5:
500 case 9:
501 case 15:
502 sound.playFX(34);
503 break;
504 case 2:
505 case 7:
506 case 10:
507 case 13:
508 sound.playFX(33);
509 break;
510 default:
511 break;
512 }
513
514 LOAD_VORTEX;
515 cast1[idx1 - 1].draw(0, idx2, Common::Point(0, 0));
516 cast2[idx1 - 1].draw(0, idx2, Common::Point(0, 100));
517 WAIT(3);
518 }
519 }
520
521 // Fade in of Alamar
522 for (int idx = 0; idx < 16; ++idx) {
523 LOAD_VORTEX;
524
525 if (idx < 7)
526 darkLord[0].draw(0, idx);
527 else if (idx < 11)
528 darkLord[1].draw(0, idx - 7);
529 else
530 darkLord[2].draw(0, idx - 11);
531
532 switch (cloudsCtr - 1) {
533 case 0:
534 case 4:
535 case 8:
536 case 14:
537 sound.playFX(34);
538 break;
539 case 1:
540 case 6:
541 case 9:
542 case 12:
543 sound.playFX(33);
544 break;
545 default:
546 break;
547 }
548
549 WAIT(3);
550 }
551 sound.setMusicPercent(60);
552 _subtitles.setLine(11);
553
554 // Alamar's monologue
555 for (int idx = 0; idx < (sound._subtitles ? 4 : 3); ++idx) {
556 switch (idx) {
557 case 0:
558 // You have defeated my general, Lord Xeen
559 sound.playVoice("dark1.voc");
560 break;
561 case 1:
562 // And foiled my plans to conquer this world
563 sound.playVoice("dark2.voc");
564 break;
565 case 2:
566 // But the Dark Side will always be mine
567 sound.playVoice("dark3.voc");
568 break;
569 default:
570 // Laugh
571 sound.playVoice("darklaff.voc");
572 sound.setMusicPercent(75);
573 break;
574 }
575
576 do {
577 LOAD_VORTEX;
578 darkLord[2].draw(0, getSpeakingFrame(2, 6));
579
580 switch (cloudsCtr - 1) {
581 case 0:
582 case 4:
583 case 8:
584 case 14:
585 sound.playFX(34);
586 break;
587 case 1:
588 case 6:
589 case 9:
590 case 12:
591 sound.playFX(33);
592 break;
593 default:
594 break;
595 }
596
597 _subtitles.show();
598 WAIT(3);
599 } while (sound.isSoundPlaying() || (idx == 3 && _subtitles.active()));
600 }
601
602 if (!sound._subtitles) {
603 // Laugh
604 sound.playVoice("darklaff.voc");
605 sound.setMusicPercent(75);
606 }
607
608 // Alamar fade out
609 for (int idx = 12; idx >= 0; --idx) {
610 LOAD_VORTEX;
611
612 if (idx < 7)
613 darkLord[0].draw(0, idx);
614 else if (idx < 11)
615 darkLord[1].draw(0, idx - 7);
616 else
617 darkLord[2].draw(0, idx - 11);
618
619 switch (cloudsCtr - 1) {
620 case 0:
621 case 4:
622 case 8:
623 case 14:
624 sound.playFX(34);
625 break;
626 case 1:
627 case 6:
628 case 9:
629 case 12:
630 sound.playFX(33);
631 break;
632 default:
633 break;
634 }
635
636 WAIT(3);
637 }
638
639 sound.stopSound();
640 sound.playSong("endgame.m");
641 screen.fadeOut();
642 return true;
643 }
644
showCloudsEnding2()645 bool CloudsCutscenes::showCloudsEnding2() {
646 Screen &screen = *_vm->_screen;
647 Sound &sound = *_vm->_sound;
648
649 SpriteResource king("king.end"), people("people.end"), crodo("crodo.end"),
650 kingCord("kingcord.end");
651
652 // Later at Castle Burlock
653 screen.loadPalette("endgame.pal");
654 screen.loadBackground("later.raw");
655 screen.fadeIn();
656 WAIT(100);
657 screen.fadeOut();
658
659 // Horizontal pan to the right within throne room
660 screen.loadBackground("throne1.raw");
661 screen.loadPage(0);
662 screen.loadBackground("throne2.raw");
663 screen.loadPage(1);
664
665 int xp2 = SCREEN_WIDTH;
666 bool fadeFlag = true;
667 for (int ctr = SCREEN_WIDTH, xp1 = 117, xp3 = 0; ctr > 0; --ctr, xp1 -= 2, ++xp3) {
668 screen.horizMerge(xp3);
669 people.draw(0, 0, Common::Point(xp1, 68), SPRFLAG_800);
670 if (xp3 > 250) {
671 crodo.draw(0, 0, Common::Point(xp2, 68), SPRFLAG_800);
672 xp2 -= 2;
673 if (xp2 < 181)
674 xp2 = 181;
675 }
676
677 if (ctr % 2) {
678 WAIT(1);
679 }
680 if (fadeFlag) {
681 screen.fadeIn();
682 fadeFlag = false;
683 }
684 }
685
686 screen.horizMerge(SCREEN_WIDTH);
687 crodo.draw(0, 0, Common::Point(xp2, 68), SPRFLAG_800);
688 screen.freePages();
689 WAIT(5);
690
691 Graphics::ManagedSurface savedBg;
692 savedBg.blitFrom(screen);
693
694 // Close up of King Roland
695 const int XLIST1[13] = { 0, -5, -10, -15, -20, -25, -30, -33, -27, -22, -17 };
696 const int XLIST2[13] = { 160, 145, 130, 115, 100, 85, 70, 57, 53, 48, 42, 39, 34 };
697 const int YLIST[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4 };
698
699 for (int idx = 12; idx >= 0; --idx) {
700 screen.blitFrom(savedBg);
701 king.draw(0, 0, Common::Point(XLIST1[idx], YLIST[idx]), 0, idx);
702 king.draw(0, 1, Common::Point(XLIST2[idx], YLIST[idx]), 0, idx);
703 WAIT(1);
704 }
705
706 // Congratulations adventurers
707 const char *const VOC_NAMES[3] = { "king1.voc", "king2.voc", "king3.voc" };
708 _subtitles.setLine(12);
709 for (int idx = 0; idx < 3; ++idx) {
710 sound.playVoice(VOC_NAMES[idx]);
711
712 do {
713 king.draw(0, 0, Common::Point(0, 0));
714 king.draw(0, 1, Common::Point(160, 0));
715
716 int frame = getSpeakingFrame(1, 6);
717 if (frame > 1)
718 king.draw(0, frame);
719
720 _subtitles.show();
721 WAIT(3);
722 } while (sound.isSoundPlaying() || (idx == 2 && _subtitles.active()));
723
724 king.draw(0, 0, Common::Point(0, 0));
725 king.draw(0, 1, Common::Point(160, 0));
726 WAIT(1);
727 }
728
729 screen.fadeOut();
730 return true;
731 }
732
733 const byte MONSTER_INDEXES[73] = {
734 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 76,
735 23, 16, 17, 80, 19, 20, 83, 22, 24, 25, 26, 27, 28, 29, 30,
736 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 43, 44, 45, 84,
737 47, 48, 49, 50, 51, 52, 53, 55, 56, 57, 58, 59, 60, 61, 62,
738 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 75, 88, 89
739 };
740 const int8 XARRAY[8] = { -2, -1, 0, 1, 2, 1, 0, -1 };
741 const int8 YARRAY[8] = { -2, 0, 2, 0, -1, 0, 2, 0 };
742
showCloudsEnding3()743 bool CloudsCutscenes::showCloudsEnding3() {
744 Map &map = *_vm->_map;
745 Screen &screen = *_vm->_screen;
746 Sound &sound = *_vm->_sound;
747 SpriteResource monSprites, attackSprites;
748 SpriteResource kingCord("kingcord.end"), room("room.end"), bigSky("bigsky.end");
749 Graphics::ManagedSurface savedBg;
750 int counter1 = 0;
751
752 // Show the mirror room
753 screen.loadPalette("mirror.pal");
754 screen.loadBackground("miror-s.raw");
755 screen.loadPage(0);
756 screen.loadPage(1);
757
758 room.draw(0, 0, Common::Point(0, 0));
759 room.draw(0, 1, Common::Point(160, 0));
760 screen.fadeIn();
761
762 for (int idx = 0; idx < 83; ++idx) {
763 screen.horizMerge(idx);
764 room.draw(0, 0, Common::Point(0, 0));
765 room.draw(0, 1, Common::Point(160, 0));
766 WAIT(1);
767 }
768
769 // Zooming into the mirror
770 screen.freePages();
771 savedBg.blitFrom(screen);
772
773 const int XLIST3[9] = { 0, -5, -10, -15, -24, -30, -39, -50, -59 };
774 const int YLIST3[9] = { 0, 12, 25, 37, 46, 52, 59, 64, 68 };
775 for (int idx = 8; idx >= 0; --idx) {
776 screen.blitFrom(savedBg);
777 bigSky.draw(0, 0, Common::Point(XLIST3[idx], YLIST3[idx]), 0, idx);
778 _mirrBack.draw(0, 0, Common::Point(XLIST3[idx], YLIST3[idx]), 0, idx);
779 WAIT(1);
780 }
781
782 // Roland and Crodo moving in to look at mirror
783 const int DELTA = 2;
784 for (int idx = 0, xc1 = -115, yp = SCREEN_HEIGHT, xc2 = 335;
785 idx < 115; idx += DELTA, xc1 += DELTA, yp -= DELTA, xc2 -= DELTA) {
786 ROTATE_BG;
787
788 _mirrBack.draw(0, 0);
789 _mirror.draw(0, 0);
790 kingCord.draw(0, 0, Common::Point(xc1, yp), SPRFLAG_800);
791 kingCord.draw(0, 1, Common::Point(xc2, yp), SPRFLAG_800);
792 WAIT(1);
793 }
794
795 ROTATE_BG;
796 _mirrBack.draw(0, 0);
797 _mirror.draw(0, 0);
798 kingCord.draw(0, 0, Common::Point(0, 85), SPRFLAG_800);
799 kingCord.draw(0, 1, Common::Point(220, 85), SPRFLAG_800);
800
801 // Loop through showing each monster
802 for (int monsterCtr = 0; monsterCtr < 73; ++monsterCtr) {
803 MonsterStruct &mon = map._monsterData[MONSTER_INDEXES[monsterCtr]];
804 monSprites.load(Common::String::format("%03d.mon", mon._imageNumber));
805 attackSprites.load(Common::String::format("%03d.att", mon._imageNumber));
806
807 for (int frameCtr = 0; frameCtr < 8; ++frameCtr) {
808 ROTATE_BG;
809 counter1 = (counter1 + 1) % 8;
810 Common::Point monPos(31, 10);
811 if (mon._flying) {
812 monPos.x += XARRAY[counter1];
813 monPos.y += YARRAY[counter1];
814 }
815
816 _mirrBack.draw(0, 0);
817 monSprites.draw(0, frameCtr, monPos);
818 _mirror.draw(0, 0);
819 kingCord.draw(0, 0, Common::Point(0, 85), SPRFLAG_800);
820 kingCord.draw(0, 1, Common::Point(220, 85), SPRFLAG_800);
821 WAIT(1);
822 }
823
824 for (int frameCtr = 0; frameCtr < 3; ++frameCtr) {
825 if (frameCtr == 2)
826 sound.playVoice(Common::String::format("%s.voc", mon._attackVoc.c_str()));
827
828 ROTATE_BG;
829 counter1 = (counter1 + 1) % 8;
830 Common::Point monPos(31, 10);
831 if (mon._flying) {
832 monPos.x += XARRAY[counter1];
833 monPos.y += YARRAY[counter1];
834 }
835
836 _mirrBack.draw(0, 0);
837 attackSprites.draw(0, frameCtr, monPos);
838 _mirror.draw(0, 0);
839 kingCord.draw(0, 0, Common::Point(0, 85), SPRFLAG_800);
840 kingCord.draw(0, 1, Common::Point(220, 85), SPRFLAG_800);
841 WAIT(1);
842 }
843
844 for (int idx = 0; idx < 15; ++idx) {
845 ROTATE_BG;
846 counter1 = (counter1 + 1) % 8;
847 Common::Point monPos(31, 10);
848 if (mon._flying) {
849 monPos.x += XARRAY[counter1];
850 monPos.y += YARRAY[counter1];
851 }
852
853 _mirrBack.draw(0, 0);
854 attackSprites.draw(0, 2, monPos);
855 _mirror.draw(0, 0);
856 kingCord.draw(0, 0, Common::Point(0, 85), SPRFLAG_800);
857 kingCord.draw(0, 1, Common::Point(220, 85), SPRFLAG_800);
858 WAIT(1);
859 }
860
861 int powNum = getSpeakingFrame(0, 5);
862 sound.stopSound();
863 sound.playSound(Common::String::format("pow%d.voc", powNum));
864
865 for (int idx = 0; idx < 7; ++idx) {
866 ROTATE_BG;
867 counter1 = (counter1 + 1) % 8;
868 Common::Point monPos(31, 10);
869 if (mon._flying) {
870 monPos.x += XARRAY[counter1];
871 monPos.y += YARRAY[counter1];
872 }
873
874 _mirrBack.draw(0, 0);
875 attackSprites.draw(0, 2, monPos);
876 _mirror.draw(0, 0);
877 kingCord.draw(0, 0, Common::Point(0, 85), SPRFLAG_800);
878 kingCord.draw(0, 1, Common::Point(220, 85), SPRFLAG_800);
879 WAIT(1);
880 }
881 }
882
883 doScroll(true, false);
884 return true;
885 }
886
showCloudsEnding4(uint finalScore)887 bool CloudsCutscenes::showCloudsEnding4(uint finalScore) {
888 EventsManager &events = *_vm->_events;
889 Screen &screen = *_vm->_screen;
890 Windows &windows = *_vm->_windows;
891 SpriteResource endText("endtext.end");
892
893 ROTATE_BG;
894 _mirrBack.draw(0, 0);
895 _mirror.draw(0, 0);
896 doScroll(false, false);
897
898 // Congratulations your final score
899 for (int idx = 0; idx < 19; ++idx) {
900 ROTATE_BG;
901 _mirrBack.draw(0, 0);
902 _mirror.draw(0, 0);
903 endText.draw(0, idx);
904 WAIT(1);
905 }
906
907 // Random animation of score numbers
908 int frames[10];
909 const int FRAMEX[10] = { 64, 83, 102, 121, 140, 159, 178, 197, 216, 235 };
910 for (int idx1 = 0; idx1 < 30; ++idx1) {
911 for (int idx2 = 0; idx2 < 10; ++idx2)
912 frames[idx2] = getSpeakingFrame(20, 29);
913
914 ROTATE_BG;
915 _mirrBack.draw(0, 0);
916 _mirror.draw(0, 0);
917 endText.draw(0, 19);
918 for (int idx2 = 0; idx2 < 10; ++idx2)
919 endText.draw(0, frames[idx2], Common::Point(FRAMEX[idx2], 73));
920
921 WAIT(2);
922 }
923
924 // Animate changing the score digits to the actual final score
925 Common::String scoreStr = Common::String::format("%.10u", finalScore);
926 for (int idx1 = 0; idx1 < 10; ++idx1) {
927 for (int idx2 = 0; idx2 < 10; ++idx2)
928 frames[idx2] = getSpeakingFrame(20, 29);
929
930 for (int idx2 = 0; idx2 <= idx1; ++idx2)
931 frames[9 - idx2] = (byte)scoreStr[9 - idx2] - 28;
932
933 ROTATE_BG;
934 _mirrBack.draw(0, 0);
935 _mirror.draw(0, 0);
936 endText.draw(0, 19);
937
938 for (int idx2 = 0; idx2 < 10; ++idx2)
939 endText.draw(0, frames[idx2], Common::Point(FRAMEX[idx2], 73));
940
941 WAIT(2);
942 }
943
944 // Move the score vertically down
945 for (int idx1 = 0; idx1 < 38; ++idx1) {
946 ROTATE_BG;
947 _mirrBack.draw(0, 0);
948 _mirror.draw(0, 0);
949 endText.draw(0, 19);
950
951 for (int idx2 = 0; idx2 < 10; ++idx2)
952 endText.draw(0, frames[idx2], Common::Point(FRAMEX[idx2], 73 + idx1));
953
954 WAIT(1);
955 }
956
957 // Show two screens worth of text, with prompt to press a key
958 windows[28].setBounds(Common::Rect(63, 60, 254, 160));
959
960 for (int idx = 1; idx <= 2; ++idx) {
961 events.clearEvents();
962 do {
963 ROTATE_BG;
964 _mirrBack.draw(0, 0);
965 _mirror.draw(0, 0);
966 endText.draw(0, 19);
967
968 for (int idx2 = 0; idx2 < 10; ++idx2)
969 endText.draw(0, frames[idx2], Common::Point(FRAMEX[idx2], 110));
970 windows[28].writeString(idx == 1 ? Res.CLOUDS_CONGRATULATIONS1 :
971 Res.CLOUDS_CONGRATULATIONS2);
972
973 events.updateGameCounter();
974 events.wait(1, false);
975 } while (!events.isKeyMousePressed());
976 }
977
978 doScroll(true, false);
979 screen.fadeOut();
980
981 return true;
982 }
983
showCloudsEnding5()984 bool CloudsCutscenes::showCloudsEnding5() {
985 Screen &screen = *_vm->_screen;
986 Sound &sound = *_vm->_sound;
987 SpriteResource king("king.end");
988
989 king.draw(0, 0, Common::Point(0, 0));
990 king.draw(0, 1, Common::Point(160, 0));
991 screen.fadeIn();
992 _subtitles.setLine(13);
993
994 sound.playVoice("king4.voc");
995 do {
996 king.draw(0, 0, Common::Point(0, 0));
997 king.draw(0, 1, Common::Point(160, 0));
998 int frame = getSpeakingFrame(1, 6);
999 if (frame > 1)
1000 king.draw(0, frame);
1001
1002 WAIT(3);
1003 } while (sound.isSoundPlaying() || _subtitles.active());
1004
1005 king.draw(0, 0, Common::Point(0, 0));
1006 king.draw(0, 1, Common::Point(160, 0));
1007 WAIT(1);
1008 return true;
1009 }
1010
loadScreen(const Common::String & name)1011 void CloudsCutscenes::loadScreen(const Common::String &name) {
1012 Screen &screen = *_vm->_screen;
1013 File fSrc(name);
1014 byte *destP = (byte *)screen.getPixels();
1015 byte *destEndP = (byte *)destP + SCREEN_WIDTH * SCREEN_HEIGHT;
1016
1017 // Setup reference arrays
1018 #define ARRAY_SIZE 314
1019 #define ARRAY_LAST1 ((ARRAY_SIZE - 1) * 2)
1020 #define ARRAY_LAST2 ((ARRAY_SIZE - 1) * 2 + 1)
1021 #define BUFFER_SIZE 0x1000
1022 uint array2[ARRAY_SIZE * 2], array3[ARRAY_SIZE * 2];
1023 uint array4[ARRAY_SIZE * 3];
1024 byte buffer[BUFFER_SIZE];
1025
1026 for (int idx = 0; idx < ARRAY_SIZE; ++idx) {
1027 array3[idx] = 1;
1028 array4[idx + 627] = idx * 2;
1029 array2[idx] = idx * 2 + (ARRAY_SIZE * 4 - 2);
1030 }
1031
1032 for (int ctr = 0, idx = 0, idx2 = ARRAY_SIZE; ctr < (ARRAY_SIZE - 1); ++ctr, idx += 2, ++idx2) {
1033 array3[idx2] = array3[idx] + array3[idx + 1];
1034 array2[idx2] = idx * 2;
1035 array4[idx] = array4[idx + 1] = idx2 * 2;
1036 }
1037 array4[ARRAY_LAST1] = 0;
1038 array3[ARRAY_LAST2] = (uint)-1;
1039 array2[ARRAY_LAST2] = 4036;
1040 uint16 bits = 0x8000;
1041
1042 // Get the decompressed size and default buffer contents
1043 uint16 bytePair;
1044 fSrc.read((byte *)&bytePair, 2);
1045 Common::fill((uint16 *)buffer, (uint16 *)(buffer + BUFFER_SIZE),
1046 bytePair);
1047
1048 int count = fSrc.readUint16BE();
1049 assert(count == (SCREEN_WIDTH * SCREEN_HEIGHT));
1050
1051 for (int byteIdx = 0; byteIdx < count; ) {
1052 assert(fSrc.pos() < fSrc.size());
1053
1054 int vMin = array2[(ARRAY_SIZE - 1) * 2];
1055 int vThreshold = ARRAY_SIZE * 4 - 2;
1056 while (vMin < vThreshold) {
1057 bool flag = (bits & 0x8000);
1058 bits <<= 1;
1059
1060 if (!bits) {
1061 bits = fSrc.readUint16BE();
1062 flag = (bits & 0x8000);
1063 bits = (bits << 1) | 1;
1064 }
1065
1066 vMin = array2[vMin / 2 + (flag ? 1 : 0)];
1067 }
1068
1069 vMin -= vThreshold;
1070
1071 if (array3[ARRAY_LAST1] == 0x8000) {
1072 for (int ctr = 0, ctr2 = 0; ctr < (ARRAY_SIZE * 2); ++ctr) {
1073 if (array2[ctr] >= (ARRAY_SIZE * 4 - 1)) {
1074 array3[ctr2] = (array3[ctr] + 1) / 2;
1075 array2[ctr2] = array2[ctr];
1076 ++ctr2;
1077 }
1078 }
1079
1080 for (int ctr = 0, ctr2 = ARRAY_SIZE; ctr < ARRAY_SIZE; ctr += 2, ++ctr2) {
1081 int currVal = array3[ctr] + array3[ctr + 1];
1082 array3[ctr2] = currVal;
1083 int ctr3 = ctr2;
1084 do {
1085 --ctr3;
1086 } while (array3[ctr3] >= array3[ctr2]);
1087 ++ctr3;
1088
1089 int diff = ctr2 - ctr3;
1090 uint *pDest = &array3[ctr2];
1091 Common::copy(pDest - 1, pDest - 1 + diff, pDest);
1092 array3[ctr3] = currVal;
1093
1094 pDest = &array2[ctr2];
1095 Common::copy(pDest - 1, pDest - 1 + diff, pDest);
1096 array2[ctr3] = ctr * 2;
1097 }
1098
1099 uint *arrEndP = &array4[ARRAY_SIZE * 2 - 1];
1100 for (int ctr = 0, val = 0; ctr < ARRAY_SIZE * 2; ++ctr, val += 2) {
1101 uint *arrP = &array4[array2[ctr] / 2];
1102 if (arrP < arrEndP)
1103 *arrP = val;
1104 }
1105 }
1106
1107 int offset = array4[627 + vMin / 2] / 2;
1108 do {
1109 int offset2 = offset;
1110 uint val = ++array3[offset2];
1111 if (val > array3[offset2 + 1]) {
1112 while (val > array3[++offset2])
1113 ;
1114 --offset2;
1115
1116 array3[offset] = array3[offset2];
1117 array3[offset2] = val;
1118
1119 int offset3 = array2[offset] / 2;
1120 array4[offset3] = offset2 * 2;
1121 if ((offset3 * 2) < (ARRAY_SIZE * 4 - 2))
1122 array4[offset3 + 1] = offset2 * 2;
1123
1124 int offset4 = array2[offset2] / 2;
1125 array2[offset2] = offset3 * 2;
1126 array4[offset4] = offset * 2;
1127 if ((offset4 * 2) < (ARRAY_SIZE * 4 - 2))
1128 array4[offset4 + 1] = offset * 2;
1129
1130 array2[offset] = offset4 * 2;
1131 offset = offset2;
1132 }
1133 } while ((offset = array4[offset] / 2) != 0);
1134
1135 vMin /= 2;
1136 if (vMin < 256) {
1137 // Single byte write to destination
1138 *destP++ = (byte)vMin;
1139 int buffOffset = array2[ARRAY_LAST2];
1140 array2[ARRAY_LAST2] = (buffOffset + 1) & 0xfff;
1141 buffer[buffOffset] = (byte)vMin;
1142 ++byteIdx;
1143 continue;
1144 }
1145
1146 uint16 bitsLow = bits, bitsHigh = 0;
1147 for (int ctr = 8; ctr > 0; --ctr) {
1148 bool highBit = bitsLow & 0x8000;
1149 bitsLow <<= 1;
1150
1151 if (bitsLow) {
1152 bitsHigh = (bitsHigh << 1) | (highBit ? 1 : 0);
1153 } else {
1154 bitsLow = fSrc.readUint16BE();
1155
1156 byte loBit = 1;
1157 do {
1158 bitsHigh = (bitsHigh << 1) | ((bitsLow & 0x8000) ? 1 : 0);
1159 bitsLow = (bitsLow << 1) | (loBit ? 1 : 0);
1160 loBit = 0;
1161 } while (--ctr > 0);
1162 break;
1163 }
1164 }
1165 bits = bitsLow;
1166
1167 int t2Val = _DECODE_TABLE2[bitsHigh] << 6;
1168 int tCount = _DECODE_TABLE1[bitsHigh] - 2;
1169
1170 for (int ctr = 0; ctr < tCount; ++ctr) {
1171 bool highBit = bits & 0x8000;
1172 bits <<= 1;
1173 if (!bits) {
1174 bits = fSrc.readUint16BE();
1175 highBit = bits & 0x8000;
1176 bits = (bits << 1) | 1;
1177 }
1178
1179 bitsHigh = (bitsHigh << 1) | (highBit ? 1 : 0);
1180 }
1181
1182 t2Val |= (bitsHigh & 0x3F);
1183 uint &last2 = array2[ARRAY_LAST2];
1184 int buffOffset = last2 - t2Val - 1;
1185
1186 for (int ctr = 0; ctr < vMin - 253; ++ctr, ++buffOffset) {
1187 buffOffset &= 0xfff;
1188 byte b = buffer[buffOffset];
1189 *destP++ = b;
1190
1191 buffer[last2] = b;
1192 last2 = (last2 + 1) & 0xfff;
1193 ++byteIdx;
1194 }
1195 }
1196
1197 assert(destP == destEndP);
1198 screen.markAllDirty();
1199 }
1200
1201 const char *const CloudsCutscenes::_INTRO_VOCS[14] = {
1202 "crodo1.voc", "crodo2.voc", "iamking.voc", "crodo3.voc",
1203 "ya1.voc", "crodo4a.voc", "crodo4b.voc", "crodo4c.voc",
1204 "xeenlaff.voc", "tiger2&.voc", "crodo5.voc", "crodo6.voc",
1205 "xeenlaff.voc", "tiger2&.voc"
1206 };
1207
1208 const int CloudsCutscenes::_INTRO_FRAMES_LOOKUP[14] = {
1209 0, 1, 0, 2, 0, 3, 4, 5, 0, 0, 6, 7, 0, 0
1210 };
1211
1212 const int CloudsCutscenes::_INTRO_FRAMES_VALS[8][32] = {
1213 {
1214 4, 2, 3, 0, 2, 3, 2, 0, 1, 1, 3, 4, 3, 2, 4, 2,
1215 3, 4, 3, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1216 }, {
1217 3, 2, 3, 2, 4, 3, 0, 3, 2, 2, 3, 1, 2, 3, 3, 3,
1218 2, 3, 2, 3, 2, 0, 3, 2, 0, 0, 0, 0, 0, 0, 2, 4
1219 }, {
1220 3, 1, 2, 3, 0, 3, 4, 3, 2, 3, 0, 3, 2, 3, 2, 1,
1221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3
1222 }, {
1223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 3
1225 }, {
1226 4, 2, 2, 3, 2, 3, 3, 4, 2, 4, 2, 0, 3, 2, 3, 2,
1227 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 2, 3
1228 }, {
1229 2, 0, 2, 3, 2, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0,
1230 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 3, 2, 3, 1
1231 }, {
1232 3, 2, 0, 2, 4, 2, 3, 2, 3, 2, 0, 0, 0, 0, 0, 0,
1233 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 4, 3, 4, 0, 2
1234 }, {
1235 3, 2, 4, 1, 2, 4, 3, 2, 3, 0, 2, 2, 0, 3, 2, 3,
1236 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1237 }
1238 };
1239
1240 const uint CloudsCutscenes::_INTRO_FRAMES_WAIT[8][32] = {
1241 {
1242 2, 5, 6, 9, 10, 11, 12, 13, 14, 23, 25, 29, 31, 35, 38, 41,
1243 42, 45, 50, 52, 55, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0
1244 }, {
1245 1, 4, 6, 8, 9, 11, 13, 15, 17, 18, 19, 22, 28, 29, 30, 31,
1246 0, 39, 0, 44, 0, 50, 51, 0, 54, 0, 0, 0, 0, 0, 0, 4
1247 }, {
1248 6, 9, 11, 13, 15, 19, 21, 23, 25, 27, 28, 31, 35, 39, 40, 0,
1249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 5, 7
1250 }, {
1251 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1252 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 4
1253 }, {
1254 5, 9, 10, 11, 13, 15, 18, 23, 26, 31, 33, 36, 37, 41, 43, 45,
1255 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 12
1256 }, {
1257 14, 17, 20, 23, 27, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 8, 11, 13
1259 }, {
1260 15, 16, 17, 19, 21, 24, 24, 27, 34, 35, 0, 0, 0, 0, 0, 0,
1261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 7, 10, 11, 13
1262 }, {
1263 17, 19, 22, 23, 26, 30, 32, 34, 40, 43, 47, 52, 53, 55, 57, 60,
1264 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1265 }
1266 };
1267
1268 const byte CloudsCutscenes::_DECODE_TABLE1[256] = {
1269 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1270 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1271 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1272 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1273 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
1274 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1275 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1276 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1277 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
1278 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1279 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1280 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
1281 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1282 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1283 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
1284 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8
1285 };
1286
1287 const byte CloudsCutscenes::_DECODE_TABLE2[256] = {
1288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1290 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1291 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1292 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1293 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
1294 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
1295 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,
1296 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11,
1297 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
1298 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
1299 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
1300 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31,
1301 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39,
1302 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
1303 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
1304 };
1305
1306 } // End of namespace WorldOfXeen
1307 } // End of namespace Xeen
1308