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/eob.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 EoBIntroPlayer {
37 public:
38 	EoBIntroPlayer(EoBEngine *vm, Screen_EoB *screen);
~EoBIntroPlayer()39 	~EoBIntroPlayer() {}
40 
41 	void start();
42 
43 private:
44 	void openingCredits();
45 	void tower();
46 	void orb();
47 	void waterdeepEntry();
48 	void king();
49 	void hands();
50 	void waterdeepExit();
51 	void tunnel();
52 
53 	void loadAndSetPalette(const char *filename);
54 	void copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step);
55 	void whirlTransition();
56 
57 	EoBEngine *_vm;
58 	Screen_EoB *_screen;
59 
60 	const char *const *_filesOpening;
61 	const char *const *_filesTower;
62 	const char *const *_filesOrb;
63 	const char *const *_filesWdEntry;
64 	const char *const *_filesKing;
65 	const char *const *_filesHands;
66 	const char *const *_filesWdExit;
67 	const char *const *_filesTunnel;
68 	const uint8 *_openingFrmDelay;
69 	const uint8 *_wdEncodeX;
70 	const uint8 *_wdEncodeY;
71 	const uint8 *_wdEncodeWH;
72 	const uint16 *_wdDsX;
73 	const uint8 *_wdDsY;
74 	const uint8 *_tvlX1;
75 	const uint8 *_tvlY1;
76 	const uint8 *_tvlX2;
77 	const uint8 *_tvlY2;
78 	const uint8 *_tvlW;
79 	const uint8 *_tvlH;
80 
81 	const uint8 _fillColor1;
82 	const uint8 _fillColor2;
83 };
84 
85 class EoBAmigaFinalePlayer {
86 public:
87 	EoBAmigaFinalePlayer(EoBEngine *vm, Screen_EoB *screen);
88 	~EoBAmigaFinalePlayer();
89 
90 	void start();
91 
92 private:
93 	void entry();
94 	void delivery();
95 	void inspection();
96 	void surprise();
97 	void congratulation();
98 
99 	void animateCouncil1(int numFrames, int skipFrame);
100 	void animateCouncil2(int numFrames, int skipFrame, bool withSpeechAnim);
101 	void playDialogue(int line, bool withAnim);
102 
103 	uint8 **_textShapes;
104 	uint8 *_councilAnimData1;
105 	uint8 *_councilAnimData2;
106 
107 	const uint8 *_councilAnimData3;
108 	const uint8 *_councilAnimData4;
109 	const uint8 *_eyesAnimData;
110 	const int16 *_handsAnimData;
111 	const uint8 *_textFrameDuration;
112 
113 	int _animCurFrame;
114 
115 	EoBEngine *_vm;
116 	Screen_EoB *_screen;
117 };
118 
EoBIntroPlayer(EoBEngine * vm,Screen_EoB * screen)119 EoBIntroPlayer::EoBIntroPlayer(EoBEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen),
120 	_fillColor1(vm->gameFlags().platform == Common::kPlatformAmiga ? 19 : 12), _fillColor2(vm->gameFlags().platform == Common::kPlatformAmiga ? 10 : 157) {
121 	int temp = 0;
122 	_filesOpening = _vm->staticres()->loadStrings(kEoB1IntroFilesOpening, temp);
123 	_filesTower = _vm->staticres()->loadStrings(kEoB1IntroFilesTower, temp);
124 	_filesOrb = _vm->staticres()->loadStrings(kEoB1IntroFilesOrb, temp);
125 	_filesWdEntry = _vm->staticres()->loadStrings(kEoB1IntroFilesWdEntry, temp);
126 	_filesKing = _vm->staticres()->loadStrings(kEoB1IntroFilesKing, temp);
127 	_filesHands = _vm->staticres()->loadStrings(kEoB1IntroFilesHands, temp);
128 	_filesWdExit = _vm->staticres()->loadStrings(kEoB1IntroFilesWdExit, temp);
129 	_filesTunnel = _vm->staticres()->loadStrings(kEoB1IntroFilesTunnel, temp);
130 	_openingFrmDelay = _vm->staticres()->loadRawData(kEoB1IntroOpeningFrmDelay, temp);
131 	_wdEncodeX = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeX, temp);
132 	_wdEncodeY = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeY, temp);
133 	_wdEncodeWH = _vm->staticres()->loadRawData(kEoB1IntroWdEncodeWH, temp);
134 	_wdDsX = _vm->staticres()->loadRawDataBe16(kEoB1IntroWdDsX, temp);
135 	_wdDsY = _vm->staticres()->loadRawData(kEoB1IntroWdDsY, temp);
136 	_tvlX1 = _vm->staticres()->loadRawData(kEoB1IntroTvlX1, temp);
137 	_tvlY1 = _vm->staticres()->loadRawData(kEoB1IntroTvlY1, temp);
138 	_tvlX2 = _vm->staticres()->loadRawData(kEoB1IntroTvlX2, temp);
139 	_tvlY2 = _vm->staticres()->loadRawData(kEoB1IntroTvlY2, temp);
140 	_tvlW = _vm->staticres()->loadRawData(kEoB1IntroTvlW, temp);
141 	_tvlH = _vm->staticres()->loadRawData(kEoB1IntroTvlH, temp);
142 	const uint8 *orbFadePal = _vm->staticres()->loadRawData(kEoB1IntroOrbFadePal, temp);
143 	_screen->loadPalette(orbFadePal, _screen->getPalette(2), temp);
144 }
145 
start()146 void EoBIntroPlayer::start() {
147 	_vm->_allowSkip = true;
148 	openingCredits();
149 
150 	if (!_vm->shouldQuit() && !_vm->skipFlag()) {
151 		_vm->snd_playSong(2);
152 		_screen->loadBitmap(_vm->gameFlags().platform == Common::kPlatformAmiga ? "TITLE.CPS" : (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA) ? "TITLE-E.CMP" : "TITLE-V.CMP", 3, 5, 0);
153 		_screen->convertPage(5, 2, _vm->_cgaMappingDefault);
154 		uint32 del = 120 * _vm->_tickLength;
155 		_screen->crossFadeRegion(0, 0, 0, 0, 320, 200, 2, 0);
156 		_vm->delay(del);
157 	}
158 
159 	Common::SeekableReadStream *s = _vm->resource()->createReadStream("TEXT.RAW");
160 	if (s) {
161 		s->seek(768);
162 		_screen->loadFileDataToPage(s, 5, s->size() - 768);
163 		delete s;
164 	} else {
165 		_screen->loadBitmap(_vm->gameFlags().platform == Common::kPlatformAmiga ? "TEXT.CPS" : "TEXT.CMP", 3, 5, 0);
166 	}
167 	_screen->convertPage(5, 6, _vm->_cgaMappingAlt);
168 
169 	tower();
170 	orb();
171 	waterdeepEntry();
172 	king();
173 	hands();
174 	waterdeepExit();
175 	tunnel();
176 
177 	whirlTransition();
178 	_vm->snd_stopSound();
179 	_vm->_allowSkip = false;
180 }
181 
openingCredits()182 void EoBIntroPlayer::openingCredits() {
183 	_vm->snd_playSong(1);
184 
185 	_screen->loadBitmap(_filesOpening[4], 5, 3, 0);
186 	_screen->convertPage(3, 0, _vm->_cgaMappingAlt);
187 
188 	if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
189 		_screen->fadeFromBlack(64);
190 	} else {
191 		loadAndSetPalette(_filesOpening[5]);
192 		_screen->updateScreen();
193 	}
194 
195 	_vm->delay(_openingFrmDelay[0] * _vm->_tickLength);
196 
197 	for (int i = 0; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
198 		_screen->loadBitmap(_filesOpening[i], 5, 3, 0);
199 		uint32 nextFrameTimer = _vm->_system->getMillis() + _openingFrmDelay[i + 1] * _vm->_tickLength;
200 		_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
201 		_screen->crossFadeRegion(0, 50, 0, 50, 320, 102, 4, 0);
202 		_vm->delayUntil(nextFrameTimer);
203 	}
204 
205 	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
206 		_vm->delay(50 * _vm->_tickLength);
207 }
208 
tower()209 void EoBIntroPlayer::tower() {
210 	if (_vm->shouldQuit() || _vm->skipFlag())
211 		return;
212 
213 	_screen->loadBitmap(_filesTower[1], 5, 3, 0);
214 
215 	_screen->setCurPage(2);
216 	uint8 *shp = _screen->encodeShape(0, 0, 16, 56, true, _vm->_cgaMappingAlt);
217 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
218 	_screen->clearCurPage();
219 
220 	for (int i = 0; i < 200; i += 64)
221 		_screen->copyRegion(128, 104, 96, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
222 
223 	_screen->fillRect(0, 184, 319, 199, _fillColor1);
224 	int cp = _screen->setCurPage(0);
225 
226 	whirlTransition();
227 	loadAndSetPalette(_filesTower[0]);
228 
229 	_screen->setCurPage(cp);
230 	_screen->clearCurPage();
231 
232 	for (int i = 0; i < 200; i += 64)
233 		_screen->copyRegion(128, 104, 0, i, 128, 64, 4, 2, Screen::CR_NO_P_CHECK);
234 
235 	_screen->setCurPage(0);
236 
237 	for (int i = 0; i < 64 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
238 		uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
239 		_screen->copyRegion(0, 142 - i, 96, 0, 128, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
240 		_screen->copyRegion(0, 0, 96, i + 1, 128, 167 - i, 2, 0, Screen::CR_NO_P_CHECK);
241 		if (!i)
242 			_screen->copyRegion(0, 0, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
243 		_screen->updateScreen();
244 		_vm->delayUntil(end);
245 	}
246 
247 	for (int i = 0; i < 24 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
248 		uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
249 		_screen->copyRegion(0, 79 - i, 96, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
250 		_screen->copyRegion(104, 79 - i, 200, 0, 24, 65 + i, 4, 0, Screen::CR_NO_P_CHECK);
251 		_screen->copyRegion(24, 110, 120, i + 31, 80, 34, 4, 0, Screen::CR_NO_P_CHECK);
252 		_screen->copyRegion(152, 0, 120, 32, 80, i + 1, 4, 0, Screen::CR_NO_P_CHECK);
253 		_screen->copyRegion(0, 0, 96, 65 + i, 128, 103 - i, 2, 0, Screen::CR_NO_P_CHECK);
254 		_screen->updateScreen();
255 		_vm->delayUntil(end);
256 	}
257 
258 	for (int i = 0; i < 56 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 2) {
259 		uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
260 		_screen->copyRegion(0, 56, 96, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
261 		_screen->copyRegion(104, 56, 200, i, 24, 54, 4, 0, Screen::CR_NO_P_CHECK);
262 		_screen->copyRegion(0, 110, 96, 54 + i, 128, 34, 4, 0, Screen::CR_NO_P_CHECK);
263 
264 		if (i < 32) {
265 			_screen->fillRect(128, 0, 255, i + 1, _fillColor1, 2);
266 			_screen->copyRegion(152, 0, 120, 32, 80, i + 25, 4, 0, Screen::CR_NO_P_CHECK);
267 		} else {
268 			_screen->fillRect(128, 0, 255, i + 1, _fillColor1, 2);
269 			_screen->copyRegion(152, i + 1, 120, 32 + i + 1, 80, 23, 4, 0, Screen::CR_NO_P_CHECK);
270 			_screen->copyRegion(152, 0, 152, 32, 80, i + 1, 4, 2, Screen::CR_NO_P_CHECK);
271 		}
272 
273 		_screen->drawShape(2, shp, 128, i - 55, 0);
274 		_screen->copyRegion(128, 0, 96, 0, 128, i + 1, 2, 0, Screen::CR_NO_P_CHECK);
275 		_screen->copyRegion(0, 0, 96, i + 89, 128, 79 - i, 2, 0, Screen::CR_NO_P_CHECK);
276 		_screen->updateScreen();
277 		_vm->delayUntil(end);
278 	}
279 
280 	_screen->copyRegion(0, 32, 0, 168, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
281 	_screen->updateScreen();
282 	_vm->delay(65 * _vm->_tickLength);
283 	delete[] shp;
284 }
285 
orb()286 void EoBIntroPlayer::orb() {
287 	if (_vm->shouldQuit() || _vm->skipFlag())
288 		return;
289 
290 	uint8 *shp[5];
291 	_screen->loadBitmap(_filesOrb[0], 5, 3, 0);
292 	_screen->setCurPage(2);
293 	shp[4] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
294 	_screen->loadBitmap(_filesOrb[1], 5, 3, 0);
295 	shp[3] = _screen->encodeShape(16, 0, 16, 104, true, _vm->_cgaMappingAlt);
296 
297 	_screen->fillRect(0, 0, 127, 103, _fillColor1);
298 	for (int i = 1; i < 4; i++) {
299 		copyBlurRegion(128, 0, 0, 0, 128, 104, i);
300 		shp[3 - i] = _screen->encodeShape(0, 0, 16, 104, true, _vm->_cgaMappingAlt);
301 	}
302 
303 	_screen->fillRect(0, 0, 159, 135, _fillColor1);
304 	_screen->setCurPage(0);
305 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
306 
307 	if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
308 		_screen->fadeToBlack(16);
309 		loadAndSetPalette(0);
310 	}
311 
312 	_screen->clearCurPage();
313 
314 	_vm->snd_playSoundEffect(6);
315 
316 	int startFrame = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 3 : -1;
317 	for (int i = startFrame; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
318 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
319 		if (i >= 0)
320 			_screen->drawShape(2, shp[i], 16, 16, 0);
321 		_screen->drawShape(2, shp[4], 0, 0, 0);
322 		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
323 		_screen->updateScreen();
324 		if (startFrame < 0)
325 			_vm->delayUntil(end);
326 	}
327 
328 	_screen->copyRegion(0, 64, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
329 	_screen->updateScreen();
330 
331 	if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
332 		_vm->delay(80 * _vm->_tickLength);
333 		_screen->fadePalette(_screen->getPalette(2), 48);
334 		_screen->clearCurPage();
335 	} else {
336 		_vm->delay(40 * _vm->_tickLength);
337 		_vm->snd_playSoundEffect(6);
338 	}
339 
340 	startFrame = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? -1 : 3;
341 	for (int i = startFrame; i > -2 && !_vm->shouldQuit() && !_vm->skipFlag(); i--) {
342 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
343 		_screen->fillRect(16, 16, 143, 119, _fillColor1, 2);
344 		if (i >= 0)
345 			_screen->drawShape(2, shp[i], 16, 16, 0);
346 		_screen->drawShape(2, shp[4], 0, 0, 0);
347 		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
348 		_screen->updateScreen();
349 		if (startFrame > 0)
350 			_vm->delayUntil(end);
351 	}
352 
353 	if (startFrame > 0)
354 		_vm->delay(40 * _vm->_tickLength);
355 
356 	for (int i = 0; i < 5; i++)
357 		delete[] shp[i];
358 }
359 
waterdeepEntry()360 void EoBIntroPlayer::waterdeepEntry() {
361 	if (_vm->shouldQuit() || _vm->skipFlag())
362 		return;
363 
364 	uint8 *shp[4];
365 	uint8 *shp2[31];
366 	uint8 *shp3[3];
367 
368 	loadAndSetPalette(_filesWdEntry[0]);
369 	_screen->loadBitmap(_filesWdEntry[1], 5, 3, 0);
370 
371 	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
372 		_screen->fadePalette(_screen->getPalette(0), 16);
373 
374 	_screen->setCurPage(2);
375 	shp[3] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
376 	for (int i = 1; i < 4; i++) {
377 		copyBlurRegion(0, 0, 0, 0, 160, 136, i);
378 		shp[3 - i] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
379 	}
380 	_screen->setCurPage(0);
381 
382 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
383 	_screen->fillRect(0, 168, 319, 199, _fillColor1, 0);
384 	_vm->snd_playSoundEffect(6);
385 
386 	int startFrame = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 3 : 0;
387 	for (int i = startFrame; i < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
388 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
389 		_screen->drawShape(0, shp[i], 80, 24, 0);
390 		delete[] shp[i];
391 		_screen->updateScreen();
392 		_vm->delayUntil(end);
393 	}
394 
395 	_screen->copyRegion(0, 80, 0, 168, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
396 	_screen->updateScreen();
397 	_vm->delay(50 * _vm->_tickLength);
398 
399 	_screen->setCurPage(2);
400 	shp[0] = _screen->encodeShape(20, 0, 20, 136, true, _vm->_cgaMappingAlt);
401 	_screen->loadBitmap(_filesWdEntry[2], 5, 3, 0);
402 	shp[1] = _screen->encodeShape(0, 0, 20, 136, true, _vm->_cgaMappingAlt);
403 	shp[2] = _screen->encodeShape(20, 0, 20, 136, true, _vm->_cgaMappingAlt);
404 	_screen->loadBitmap(_filesWdEntry[3], 5, 3, 0);
405 
406 	for (int i = 0; i < 31; i++)
407 		shp2[i] = _screen->encodeShape(_wdEncodeX[i], 136 + (_wdEncodeY[i] << 3), _wdEncodeWH[i], _wdEncodeWH[i] << 3, true, _vm->_cgaMappingAlt);
408 	for (int i = 0; i < 3; i++)
409 		shp3[i] = _screen->encodeShape(5 * i, 152, 5, 32, true, _vm->_cgaMappingAlt);
410 
411 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
412 
413 	for (int i = 0; i < 3 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
414 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
415 		_screen->fillRect(0, 0, 159, 135, _fillColor1, 2);
416 		_screen->drawShape(2, shp[i], 0, 0, 0);
417 		_screen->copyRegion(0, 0, 80, 24, 160, 136, 2, 0, Screen::CR_NO_P_CHECK);
418 		_screen->updateScreen();
419 		_vm->delayUntil(end);
420 	}
421 
422 	_screen->copyRegion(0, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
423 	_screen->updateScreen();
424 	_vm->delay(4 * _vm->_tickLength);
425 	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
426 	_screen->fillRect(0, 168, 319, 199, _fillColor1, 0);
427 	_screen->updateScreen();
428 	_vm->delay(4 * _vm->_tickLength);
429 	_screen->copyRegion(0, 184, 40, 184, 232, 16, 4, 0, Screen::CR_NO_P_CHECK);
430 
431 	int cx = 264;
432 	int cy = 11;
433 
434 	for (int i = 0; i < 70 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
435 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
436 
437 		_screen->copyRegion(cx - 2, cy - 2, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
438 		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
439 		_screen->copyRegion(cx - 2, cy - 2, cx - 82, cy + 22, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
440 		_screen->copyRegion(0, 0, cx - 2, cy - 2, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
441 		cx--;
442 		cy++;
443 
444 		for (int ii = 0; ii < 5; ii++) {
445 			int s = _vm->_rnd.getRandomNumber(255) % 31;
446 			_screen->drawShape(0, shp2[s], _wdDsX[s] - 80, _wdDsY[s] + 24, 0);
447 		}
448 
449 		if (!(_vm->_rnd.getRandomNumber(255) & 7))
450 			_vm->snd_playSoundEffect(_vm->_rnd.getRandomBit() ? 5 : 14);
451 
452 		_screen->updateScreen();
453 		_vm->delayUntil(end);
454 	}
455 
456 	for (int i = 0; i < 3; i++) {
457 		delete[] shp[i];
458 		delete[] shp3[i];
459 	}
460 
461 	for (int i = 0; i < 31; i++)
462 		delete[] shp2[i];
463 }
464 
king()465 void EoBIntroPlayer::king() {
466 	if (_vm->shouldQuit() || _vm->skipFlag())
467 		return;
468 
469 	_screen->loadBitmap(_filesKing[0], 5, 3, 0);
470 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
471 
472 	if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
473 		_screen->fadeToBlack(32);
474 		loadAndSetPalette(0);
475 	}
476 
477 	int x = 15;
478 	int y = 14;
479 	int w = 1;
480 	int h = 1;
481 
482 	for (int i = 0; i < 10 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
483 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
484 		_screen->copyRegion(x << 3, y << 3, x << 3, y << 3, w << 3, h << 3, 4, 0, Screen::CR_NO_P_CHECK);
485 		if (x > 6)
486 			x --;
487 		if (y > 0)
488 			y -= 2;
489 		w += 3;
490 		if (x + w > 34)
491 			w = 34 - x;
492 		h += 3;
493 		if (y + h > 23)
494 			h = 23 - y;
495 		_screen->updateScreen();
496 		_vm->delayUntil(end);
497 	}
498 
499 	_vm->delay(25 * _vm->_tickLength);
500 
501 	uint8 *shp[4];
502 	int16 dy[4];
503 	int16 stepY[4];
504 
505 	static const uint8 advEncX[] = { 0, 6, 12, 19 };
506 	static const uint8 advEncW[] = { 6, 6, 7, 6 };
507 	static const int8 modY[] = { -4, -8, -2, -2, 1, 0, 0, 0 };
508 
509 	_screen->loadBitmap(_filesKing[1], 5, 3, 0);
510 	_screen->setCurPage(2);
511 	for (int i = 0; i < 4; i++) {
512 		shp[i] = _screen->encodeShape(advEncX[i], 0, advEncW[i], 98, true, _vm->_cgaMappingAlt);
513 		dy[i] = 180 + ((_vm->_rnd.getRandomNumber(255) & 3) << 3);
514 		stepY[i] = (i * 5) & 3;
515 	}
516 
517 	_screen->copyPage(0, 4);
518 
519 	for (bool runloop = true; runloop && !_vm->shouldQuit() && !_vm->skipFlag();) {
520 		runloop = false;
521 		uint32 end = _vm->_system->getMillis() + 2 * _vm->_tickLength;
522 
523 		for (int i = 0; i < 4; i++) {
524 			if (dy[i] <= 82)
525 				continue;
526 			stepY[i] = (stepY[i] + 1) & 7;
527 			dy[i] += modY[stepY[i]];
528 
529 			if (dy[i] < 82)
530 				dy[i] = 82;
531 
532 			if (dy[i] < 180) {
533 				_screen->copyRegion((advEncX[i] + 8) << 3, dy[i] - 2, 0, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 4, Screen::CR_NO_P_CHECK);
534 				_screen->drawShape(4, shp[i], 0, dy[i], 0);
535 				_screen->copyRegion(0, dy[i] - 2, (advEncX[i] + 8) << 3, dy[i] - 2, advEncW[i] << 3, 182 - dy[i], 4, 0, Screen::CR_NO_P_CHECK);
536 			}
537 
538 			runloop = true;
539 		}
540 
541 		if (!(_vm->_rnd.getRandomNumber(255) & 3))
542 			_vm->snd_playSoundEffect(7);
543 
544 		_screen->updateScreen();
545 		_vm->delayUntil(end);
546 	}
547 
548 	_screen->copyRegion(0, 96, 0, 160, 320, 32, 6, 0, Screen::CR_NO_P_CHECK);
549 	_screen->updateScreen();
550 	_vm->delay(70 * _vm->_tickLength);
551 
552 	for (int i = 0; i < 4; i++)
553 		delete[] shp[i];
554 }
555 
hands()556 void EoBIntroPlayer::hands() {
557 	if (_vm->shouldQuit() || _vm->skipFlag())
558 		return;
559 
560 	_screen->setCurPage(2);
561 	uint8 *shp1 = _screen->encodeShape(0, 140, 21, 60, true, _vm->_cgaMappingAlt);
562 	uint8 *shp2 = _screen->encodeShape(21, 140, 12, 60, true, _vm->_cgaMappingAlt);
563 	_screen->loadBitmap(_filesHands[0], 3, 5, 0);
564 
565 	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
566 		_vm->delay(60 * _vm->_tickLength);
567 
568 	_screen->fillRect(0, 160, 319, 199, _fillColor1, 0);
569 	_screen->fillRect(0, 0, 191, 63, _fillColor2, 2);
570 	_screen->drawShape(2, shp1, 0, 4, 0);
571 	_screen->drawShape(2, shp2, 151, 4, 0);
572 	_vm->boxMorphTransition(25, 8, 18, 4, 3, 0, 21, 8, 6, 0, 28, 23);
573 	_screen->copyRegion(0, 128, 0, 176, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
574 
575 	_screen->updateScreen();
576 	_vm->delay(15 * _vm->_tickLength);
577 	_vm->snd_playSoundEffect(11);
578 
579 	for (int i = -22; i <= 20 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
580 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
581 		_screen->fillRect(0, 0, 167, 63, _fillColor2);
582 		_screen->drawShape(2, shp1, i, 4, 0);
583 		_screen->drawShape(2, shp2, 105 - i, 4, 0);
584 		_screen->copyRegion(0, 0, 144, 32, 168, 64, 2, 0, Screen::CR_NO_P_CHECK);
585 		_screen->updateScreen();
586 		_vm->delayUntil(end);
587 	}
588 
589 	_vm->snd_playSoundEffect(10);
590 
591 	delete[] shp1;
592 	delete[] shp2;
593 	_vm->delay(15 * _vm->_tickLength);
594 
595 	_screen->setCurPage(4);
596 	shp1 = _screen->encodeShape(17, 0, 11, 120, true, _vm->_cgaMappingAlt);
597 	shp2 = _screen->encodeShape(28, 112, 1, 31, true, _vm->_cgaMappingAlt);
598 	uint8 *shp3 = _screen->encodeShape(9, 138, 14, 54, true, _vm->_cgaMappingAlt);
599 
600 	_screen->setCurPage(2);
601 	_screen->fillRect(0, 0, 135, 63, _fillColor2);
602 	_screen->drawShape(2, shp1, 32, -80, 0);
603 	_screen->drawShape(2, shp2, 40, -16, 0);
604 	_vm->boxMorphTransition(18, 16, 10, 12, 0, 0, 17, 8, 17, 3, 25, 10);
605 	_vm->delay(15 * _vm->_tickLength);
606 
607 	for (int i = -80; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
608 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
609 		_screen->fillRect(0, 0, 135, 63, _fillColor2);
610 		_screen->drawShape(2, shp1, 32, i, 0);
611 		_screen->drawShape(2, shp2, 40, i + 64, 0);
612 		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
613 		_screen->updateScreen();
614 		_vm->delayUntil(end);
615 	}
616 
617 	_vm->snd_playSoundEffect(12);
618 	_vm->delay(5 * _vm->_tickLength);
619 
620 	for (int i = 0; i > -54 && !_vm->shouldQuit() && !_vm->skipFlag(); i -= 4) {
621 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
622 		_screen->fillRect(0, 0, 135, 63, _fillColor2);
623 		_screen->drawShape(2, shp3, 12, 64 + i, 0);
624 		_screen->drawShape(2, shp1, 32, i, 0);
625 		_screen->copyRegion(0, 0, 80, 96, 136, 64, 2, 0, Screen::CR_NO_P_CHECK);
626 		_screen->updateScreen();
627 		_vm->delayUntil(end);
628 	}
629 
630 	delete[] shp1;
631 	delete[] shp2;
632 	delete[] shp3;
633 	_vm->delay(15 * _vm->_tickLength);
634 
635 	_screen->setCurPage(4);
636 	shp1 = _screen->encodeShape(0, 0, 17, 136, true, _vm->_cgaMappingAlt);
637 	shp2 = _screen->encodeShape(0, 136, 9, 48, true, _vm->_cgaMappingAlt);
638 
639 	_screen->setCurPage(2);
640 	_screen->fillRect(0, 0, 143, 95, _fillColor2);
641 	_screen->drawShape(2, shp1, -56, -56, 0);
642 	_screen->drawShape(2, shp2, 52, 49, 0);
643 	_vm->boxMorphTransition(9, 6, 0, 0, 0, 0, 18, 12, 8, 11, 21, 10);
644 	_vm->delay(15 * _vm->_tickLength);
645 	_vm->snd_playSoundEffect(11);
646 
647 	for (int i = -56; i <= -8 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
648 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
649 		_screen->fillRect(0, 0, 143, 95, _fillColor2);
650 		_screen->drawShape(2, shp1, i, i, 0);
651 		_screen->drawShape(2, shp2, (i == -8) ? 55 : 52, (i == -8) ? 52 : 49, 0);
652 		_screen->copyRegion(0, 0, 0, 0, 144, 96, 2, 0, Screen::CR_NO_P_CHECK);
653 		_screen->updateScreen();
654 		_vm->delayUntil(end);
655 	}
656 
657 	_vm->snd_playSoundEffect(10);
658 	delete[] shp1;
659 	delete[] shp2;
660 	_vm->delay(30 * _vm->_tickLength);
661 
662 	_screen->setCurPage(4);
663 	shp1 = _screen->encodeShape(28, 0, 11, 40, true, _vm->_cgaMappingAlt);
664 	shp2 = _screen->encodeShape(28, 40, 10, 72, true, _vm->_cgaMappingAlt);
665 
666 	_screen->setCurPage(2);
667 	_screen->fillRect(0, 0, 87, 112, _fillColor2);
668 	_screen->drawShape(2, shp2, 0, 90, 0);
669 	_vm->boxMorphTransition(20, 13, 15, 6, 0, 0, 11, 14, 0, 0, 24, 16);
670 	_vm->delay(15 * _vm->_tickLength);
671 
672 	int dy = 90;
673 	for (int i = -40; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
674 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
675 		_screen->fillRect(0, 0, 87, 112, _fillColor2);
676 		_screen->drawShape(2, shp2, 0, dy, 0);
677 		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
678 		_screen->updateScreen();
679 		_vm->delayUntil(end);
680 		dy -= 5;
681 	}
682 
683 	_vm->snd_playSoundEffect(13);
684 
685 	for (int i = -40; i <= 0 && !_vm->shouldQuit() && !_vm->skipFlag(); i += 4) {
686 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
687 		_screen->fillRect(0, 0, 87, 39, _fillColor2);
688 		_screen->drawShape(2, shp1, 0, i, 0);
689 		_screen->copyRegion(0, 0, 120, 48, 88, 112, 2, 0, Screen::CR_NO_P_CHECK);
690 		_screen->updateScreen();
691 		_vm->delayUntil(end);
692 	}
693 
694 	delete[] shp1;
695 	delete[] shp2;
696 	_vm->delay(48 * _vm->_tickLength);
697 }
698 
waterdeepExit()699 void EoBIntroPlayer::waterdeepExit() {
700 	if (_vm->shouldQuit() || _vm->skipFlag())
701 		return;
702 
703 	uint8 *shp2[31];
704 	uint8 *shp3[3];
705 
706 	_screen->loadBitmap(_filesWdExit[0], 5, 3, 0);
707 	_screen->setCurPage(2);
708 	for (int i = 0; i < 31; i++)
709 		shp2[i] = _screen->encodeShape(_wdEncodeX[i], 136 + (_wdEncodeY[i] << 3), _wdEncodeWH[i], _wdEncodeWH[i] << 3, true, _vm->_cgaMappingAlt);
710 	for (int i = 0; i < 3; i++)
711 		shp3[i] = _screen->encodeShape(5 * i + 15, 152, 5, 32, true, _vm->_cgaMappingAlt);
712 	uint8 *shp1 = _screen->encodeShape(31, 136, 5, 32, true, _vm->_cgaMappingAlt);
713 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
714 	_screen->copyRegion(0, 0, 0, 136, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
715 	_screen->fillRect(0, 168, 319, 199, _fillColor1, 0);
716 	_screen->copyRegion(160, 0, 80, 24, 160, 136, 4, 0, Screen::CR_NO_P_CHECK);
717 
718 	int cx = 140;
719 	int cy = 128;
720 
721 	for (int i = 0; i < 70 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
722 		uint32 end = _vm->_system->getMillis() + 3 * _vm->_tickLength;
723 		int fx = cx - 2;
724 		if (fx < 160)
725 			fx = 160;
726 		int fy = cy - 2;
727 		if (fy > 98)
728 			fy = 98;
729 
730 		_screen->copyRegion(fx, fy, 0, 0, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
731 		_screen->drawShape(4, shp3[((i & 3) == 3) ? 1 : (i & 3)], cx, cy, 0);
732 		_screen->drawShape(4, shp1, 160, 104, 0);
733 		_screen->copyRegion(fx, fy, fx - 80, fy + 24, 48, 36, 4, 0, Screen::CR_NO_P_CHECK);
734 		_screen->copyRegion(0, 0, fx, fy, 48, 36, 4, 4, Screen::CR_NO_P_CHECK);
735 		cx++;
736 		cy--;
737 
738 		for (int ii = 0; ii < 5; ii++) {
739 			int s = _vm->_rnd.getRandomNumber(255) % 31;
740 			_screen->drawShape(0, shp2[s], _wdDsX[s] - 80, _wdDsY[s] + 24, 0);
741 		}
742 
743 		if (!(_vm->_rnd.getRandomNumber(255) & 7))
744 			_vm->snd_playSoundEffect(_vm->_rnd.getRandomBit() ? 5 : 14);
745 
746 		_screen->updateScreen();
747 		_vm->delayUntil(end);
748 	}
749 
750 	for (int i = 0; i < 3; i++)
751 		delete[] shp3[i];
752 
753 	for (int i = 0; i < 31; i++)
754 		delete[] shp2[i];
755 	delete[] shp1;
756 
757 	_screen->setCurPage(0);
758 	_screen->fillRect(0, 168, 319, 199, _fillColor1, 0);
759 	_screen->copyRegion(0, 136, 0, 0, 48, 36, 0, 4, Screen::CR_NO_P_CHECK);
760 
761 	int dstPage = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 4 : 5;
762 	_screen->loadBitmap(_filesWdExit[2], 3, dstPage, 0);
763 	_screen->convertPage(dstPage, 2, _vm->_cgaMappingAlt);
764 	whirlTransition();
765 	loadAndSetPalette(_filesWdExit[1]);
766 	_vm->delay(6 * _vm->_tickLength);
767 
768 	_screen->copyRegion(0, 144, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
769 
770 	cx = 0;
771 	cy = 136;
772 	int dy = 0;
773 	for (int i = 0; i < 19 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
774 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
775 		_screen->copyRegion(cx, cy, 80, dy + 16, 160, 8, 2, 0, Screen::CR_NO_P_CHECK);
776 		cy += 8;
777 		dy += 8;
778 		if (i == 6) {
779 			cx = 160;
780 			cy = 0;
781 		}
782 		_screen->updateScreen();
783 		_vm->delayUntil(end);
784 	}
785 
786 	_vm->snd_playSong(3);
787 	_vm->delay(60 * _vm->_tickLength);
788 
789 	for (int i = 0; i < 56 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
790 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
791 		_screen->copyRegion(0, 136 + i, 80, 16, 160, 56 - i, 2, 0, Screen::CR_NO_P_CHECK);
792 		_screen->copyRegion(160, 0, 80, 72 - i, 160, 96 + i, 2, 0, Screen::CR_NO_P_CHECK);
793 		_screen->updateScreen();
794 		_vm->delayUntil(end);
795 	}
796 
797 	for (int i = 1; i < 48 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
798 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
799 		_screen->copyRegion(160, i, 80, 16, 160, 152, 2, 0, Screen::CR_NO_P_CHECK);
800 		_screen->updateScreen();
801 		_vm->delayUntil(end);
802 	}
803 
804 	_screen->loadBitmap(_filesWdExit[3], 3, dstPage, 0);
805 	_screen->convertPage(dstPage, 2, _vm->_cgaMappingAlt);
806 	_vm->delay(30 * _vm->_tickLength);
807 	_screen->setCurPage(0);
808 	_screen->fillRect(0, 16, 319, 31, _fillColor1);
809 	_screen->fillRect(0, 136, 319, 199, _fillColor1);
810 	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
811 	loadAndSetPalette(_filesWdExit[4]);
812 	_screen->updateScreen();
813 	_vm->delay(50 * _vm->_tickLength);
814 }
815 
tunnel()816 void EoBIntroPlayer::tunnel() {
817 	if (_vm->shouldQuit() || _vm->skipFlag())
818 		return;
819 
820 	_screen->setCurPage(4);
821 	uint8 *shp2 = _screen->encodeShape(20, 0, 20, 120, true, _vm->_cgaMappingAlt);
822 	uint8 *shp1 = _screen->encodeShape(0, 0, 20, 120, true, _vm->_cgaMappingAlt);
823 	_vm->drawBlockObject(1, 4, shp2, 160, 0, 0);
824 	_vm->drawBlockObject(1, 4, shp1, 0, 0, 0);
825 	delete[] shp1;
826 	delete[] shp2;
827 
828 	for (int i = 0; i < 3 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
829 		uint32 end = _vm->_system->getMillis() + 8 * _vm->_tickLength;
830 		_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
831 		_vm->snd_playSoundEffect(7);
832 		_screen->updateScreen();
833 		_vm->delayUntil(end);
834 		_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
835 		_vm->snd_playSoundEffect(7);
836 		end = _vm->_system->getMillis() + 8 * _vm->_tickLength;
837 		_screen->updateScreen();
838 		_vm->delayUntil(end);
839 	}
840 
841 	_screen->copyRegion(0, 160, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
842 	_screen->updateScreen();
843 	_vm->delay(18 * _vm->_tickLength);
844 	_screen->copyRegion(160, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
845 	_screen->updateScreen();
846 	_vm->delay(5 * _vm->_tickLength);
847 	_screen->copyRegion(0, 122, 80, 32, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
848 	_screen->copyRegion(160, 122, 80, 92, 160, 60, 2, 0, Screen::CR_NO_P_CHECK);
849 	_screen->updateScreen();
850 	_vm->delay(5 * _vm->_tickLength);
851 	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
852 	for (int i = 0; i < 6; i++)
853 		_screen->copyRegion(i * 48, 185, 56, (i << 3) + 24, 48, 8, 2, 2, Screen::CR_NO_P_CHECK);
854 	_screen->updateScreen();
855 	_vm->delay(5 * _vm->_tickLength);
856 	_screen->copyRegion(0, 0, 80, 32, 160, 120, 2, 0, Screen::CR_NO_P_CHECK);
857 
858 	_screen->loadBitmap(_filesTunnel[0], 5, 3, 0);
859 	if (_vm->gameFlags().platform == Common::kPlatformAmiga)
860 		_screen->setScreenPalette(_screen->getPalette(0));
861 
862 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
863 	_screen->updateScreen();
864 	_vm->delay(40 * _vm->_tickLength);
865 
866 	_screen->copyRegion(264, 0, 136, 56, 48, 48, 4, 0, Screen::CR_NO_P_CHECK);
867 	_vm->snd_playSoundEffect(8);
868 	_screen->copyRegion(0, 0, 0, 0, 320, 184, 0, 2, Screen::CR_NO_P_CHECK);
869 	_screen->updateScreen();
870 	_vm->delay(16 * _vm->_tickLength);
871 	_vm->snd_playSoundEffect(4);
872 
873 	for (int i = 0; i < 30 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
874 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
875 		if (i == 0)
876 			_screen->fillRect(0, 168, 319, 199, _fillColor1, 0);
877 		_screen->copyRegion(80, 25 + (_vm->_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
878 		_screen->updateScreen();
879 		_vm->delayUntil(end);
880 	}
881 
882 	_vm->snd_playSoundEffect(9);
883 
884 	for (int i = 0; i < 6 && !_vm->shouldQuit() && !_vm->skipFlag(); i++) {
885 		uint32 end = _vm->_system->getMillis() + _vm->_tickLength;
886 		_screen->copyRegion(_tvlX1[i] << 3, _tvlY1[i], _tvlX2[i] << 3, _tvlY2[i], _tvlW[i] << 3, _tvlH[i], 4, 2, Screen::CR_NO_P_CHECK);
887 		for (int ii = 0; ii < 4 && !_vm->shouldQuit() && !_vm->skipFlag(); ii++) {
888 			_screen->updateScreen();
889 			_vm->delayUntil(end);
890 			end = _vm->_system->getMillis() + _vm->_tickLength;
891 			_screen->copyRegion(80, 25 + (_vm->_rnd.getRandomNumber(255) & 7), 80, 24, 160, 144, 2, 0, Screen::CR_NO_P_CHECK);
892 		}
893 	}
894 	_screen->copyRegion(0, 0, 0, 0, 320, 168, 2, 0, Screen::CR_NO_P_CHECK);
895 	_screen->updateScreen();
896 	_vm->delay(40 * _vm->_tickLength);
897 
898 	_screen->loadBitmap(_filesTunnel[1], 5, 3, 0);
899 	_screen->convertPage(3, 4, _vm->_cgaMappingAlt);
900 	_vm->snd_playSoundEffect(6);
901 	_screen->copyRegion(0, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
902 	_screen->updateScreen();
903 	_vm->delay(2 * _vm->_tickLength);
904 	_screen->copyRegion(160, 0, 80, 32, 160, 120, 4, 0, Screen::CR_NO_P_CHECK);
905 	_screen->updateScreen();
906 	_vm->delay(2 * _vm->_tickLength);
907 	_screen->copyRegion(0, 120, 80, 30, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
908 	_screen->copyRegion(160, 120, 80, 94, 160, 64, 4, 0, Screen::CR_NO_P_CHECK);
909 	_screen->copyRegion(0, 176, 0, 184, 320, 16, 6, 0, Screen::CR_NO_P_CHECK);
910 	_screen->setCurPage(0);
911 	_screen->updateScreen();
912 	_vm->delay(50 * _vm->_tickLength);
913 }
914 
loadAndSetPalette(const char * filename)915 void EoBIntroPlayer::loadAndSetPalette(const char *filename) {
916 	if (_vm->_configRenderMode == Common::kRenderCGA || _vm->_configRenderMode == Common::kRenderEGA)
917 		return;
918 
919 	if (_vm->gameFlags().platform != Common::kPlatformAmiga)
920 		_screen->loadPalette(filename, _screen->getPalette(0));
921 
922 	_screen->getPalette(0).fill(0, 1, 0);
923 	_screen->setScreenPalette(_screen->getPalette(0));
924 }
925 
copyBlurRegion(int x1,int y1,int x2,int y2,int w,int h,int step)926 void EoBIntroPlayer::copyBlurRegion(int x1, int y1, int x2, int y2, int w, int h, int step) {
927 	const uint8 *ptr2 = _screen->getCPagePtr(3) + y1 * 320 + x1;
928 
929 	if (step == 1) {
930 		while (h > 0) {
931 			int dx = x2;
932 			for (int i = 0; i < w; i += 2) {
933 				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
934 				_screen->setPagePixel(3, dx++, y2, 0);
935 			}
936 			dx = x2;
937 			y2++;
938 			ptr2 += 320;
939 			for (int i = 0; i < w; i += 2) {
940 				_screen->setPagePixel(3, dx++, y2, 0);
941 				_screen->setPagePixel(3, dx++, y2, ptr2[i + 1]);
942 			}
943 			y2++;
944 			ptr2 += 320;
945 			h -= 2;
946 		}
947 	} else if (step == 2) {
948 		while (h > 0) {
949 			int dx = x2;
950 			for (int i = 0; i < w; i += 2) {
951 				_screen->setPagePixel(3, dx++, y2, ptr2[i]);
952 				_screen->setPagePixel(3, dx++, y2, 0);
953 			}
954 			dx = x2;
955 			y2++;
956 			ptr2 += 320;
957 			for (int i = 0; i < w; i++)
958 				_screen->setPagePixel(3, dx++, y2, 0);
959 
960 			y2++;
961 			ptr2 += 320;
962 			h -= 2;
963 		}
964 	} else if (step == 3) {
965 		for (int i = 0; i < h; i++) {
966 			int dx = x2;
967 			if ((i % 3) == 0) {
968 				int ii = 0;
969 				for (; ii < w - 3; ii += 3) {
970 					_screen->setPagePixel(3, dx++, y2, ptr2[ii]);
971 					_screen->setPagePixel(3, dx++, y2, 0);
972 					_screen->setPagePixel(3, dx++, y2, 0);
973 				}
974 				for (; ii < w; ii++)
975 					_screen->setPagePixel(3, dx++, y2, 0);
976 			} else {
977 				for (int ii = 0; ii < w; ii++)
978 					_screen->setPagePixel(3, dx++, y2, 0);
979 			}
980 			y2++;
981 			ptr2 += 320;
982 		}
983 	}
984 }
985 
whirlTransition()986 void EoBIntroPlayer::whirlTransition() {
987 	if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
988 		_screen->fadeToBlack(48);
989 		_screen->clearPage(0);
990 		return;
991 	}
992 
993 	for (int i = 0; i < 2; i++) {
994 		for (int ii = 0; ii < 8; ii++) {
995 			uint32 e = _vm->_system->getMillis() + 3;
996 			if (ii & 1) {
997 				for (int iii = i + ii; iii < 320; iii += 8)
998 					_screen->drawClippedLine(iii, 0, iii, 199, 12);
999 			} else {
1000 				for (int iii = i + ii; iii < 200; iii += 8)
1001 					_screen->drawClippedLine(0, iii, 319, iii, 12);
1002 			}
1003 			_screen->updateScreen();
1004 			uint32 c = _vm->_system->getMillis();
1005 			if (e > c)
1006 				_vm->_system->delayMillis(e - c);
1007 		}
1008 	}
1009 }
1010 
EoBAmigaFinalePlayer(EoBEngine * vm,Screen_EoB * screen)1011 EoBAmigaFinalePlayer::EoBAmigaFinalePlayer(EoBEngine *vm, Screen_EoB *screen) : _vm(vm), _screen(screen) {
1012 	_animCurFrame = 0;
1013 	int size = 0;
1014 	_textShapes = new uint8*[10];
1015 	memset(_textShapes, 0, sizeof(uint8*) * 10);
1016 	_councilAnimData1 = new uint8[78];
1017 	memcpy(_councilAnimData1, _vm->staticres()->loadRawData(kEoB1FinaleCouncilAnim1, size), 78);
1018 	_councilAnimData2 = new uint8[78];
1019 	memcpy(_councilAnimData2, _vm->staticres()->loadRawData(kEoB1FinaleCouncilAnim2, size), 78);
1020 	_councilAnimData3 = _vm->staticres()->loadRawData(kEoB1FinaleCouncilAnim3, size);
1021 	_councilAnimData4 = _vm->staticres()->loadRawData(kEoB1FinaleCouncilAnim4, size);
1022 	_eyesAnimData = _vm->staticres()->loadRawData(kEoB1FinaleEyesAnim, size);
1023 	_handsAnimData = (const int16*)_vm->staticres()->loadRawDataBe16(kEoB1FinaleHandsAnim, size);
1024 	_textFrameDuration = _vm->staticres()->loadRawData(kEoB1FinaleTextDuration, size);;
1025 }
1026 
~EoBAmigaFinalePlayer()1027 EoBAmigaFinalePlayer::~EoBAmigaFinalePlayer() {
1028 	for (int i = 0; i < 10; ++i)
1029 		delete[] _textShapes[i];
1030 	delete[] _textShapes;
1031 	delete[] _councilAnimData1;
1032 	delete[] _councilAnimData2;
1033 }
1034 
start()1035 void EoBAmigaFinalePlayer::start() {
1036 	_screen->hideMouse();
1037 	uint32 tick = _vm->_system->getMillis() + 80 * _vm->_tickLength;
1038 
1039 	_screen->clearPage(0);
1040 	_screen->clearPage(2);
1041 	_screen->loadShapeSetBitmap("TEXT2", 5, 3);
1042 	for (int i = 0; i < 10; ++i)
1043 		_textShapes[i] = _screen->encodeShape(0, i << 4, 40, 15);
1044 	_screen->clearPage(2);
1045 
1046 	_screen->loadBitmap("COUNCILA.CPS", 2, 4, 0);
1047 	_screen->loadBitmap("COUNCILB.CPS", 2, 6, 0);
1048 
1049 	_vm->delayUntil(tick);
1050 	_vm->_eventList.clear();
1051 	_vm->_allowSkip = true;
1052 
1053 	_vm->sound()->playTrack(0);
1054 
1055 	entry();
1056 	delivery();
1057 	inspection();
1058 	surprise();
1059 	congratulation();
1060 
1061 	_vm->_allowSkip = false;
1062 	_vm->_eventList.clear();
1063 
1064 	_screen->fadeToBlack();
1065 }
1066 
entry()1067 void EoBAmigaFinalePlayer::entry() {
1068 	static uint8 textMode[] = { 1, 1, 0, 1, 1, 0 };
1069 	if (_vm->shouldQuit() || _vm->skipFlag())
1070 		return;
1071 
1072 	_screen->setScreenPalette(_screen->getPalette(0));
1073 	_screen->copyRegion(0, 0, 0, 0, 320, 72, 4, 2, Screen::CR_NO_P_CHECK);
1074 	_screen->copyRegion(0, 0, 0, 80, 320, 72, 2, 2, Screen::CR_NO_P_CHECK);
1075 
1076 	for (int i = 1; i < 21 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1077 		_screen->copyRegion((20 - i) << 3, 80, (20 - i) << 3, 48, i << 4, 72, 2, 0, Screen::CR_NO_P_CHECK);
1078 		_screen->updateScreen();
1079 		_vm->delay(2 * _vm->_tickLength);
1080 	}
1081 
1082 	for (int i = 0; i < 15 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1083 		animateCouncil1(2, -1);
1084 		_screen->updateScreen();
1085 		_vm->delay(4 * _vm->_tickLength);
1086 	}
1087 
1088 	for (int i = 0; i < 65 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1089 		animateCouncil1(_vm->_rnd.getRandomNumberRng(1, 3), -1);
1090 		_screen->updateScreen();
1091 		_vm->delay(4 * _vm->_tickLength);
1092 
1093 		if (i == 45 || i == 47) {
1094 			animateCouncil1(99, -1);
1095 			_screen->updateScreen();
1096 		}
1097 
1098 		if (i % 16 == 0)
1099 			playDialogue(i >> 4, textMode[i >> 4]);
1100 	}
1101 }
1102 
delivery()1103 void EoBAmigaFinalePlayer::delivery() {
1104 	if (_vm->shouldQuit() || _vm->skipFlag())
1105 		return;
1106 
1107 	_screen->setCurPage(4);
1108 	uint8 *shp = _screen->encodeShape(0, 72, 3, 32, true);
1109 
1110 	for (int i = 0; i < 5 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1111 		static const uint8 y[5] = { 152,  139,  131,  129,  127 };
1112 		_screen->copyRegion(120, 30, 120, 110, 56, 42, 2, 2, Screen::CR_NO_P_CHECK);
1113 		_screen->drawShape(2, shp, 153, y[i], 0);
1114 		_screen->copyRegion(120, 110, 120, 78, 56, 42, 2, 0, Screen::CR_NO_P_CHECK);
1115 		animateCouncil1(2, -1);
1116 		_screen->updateScreen();
1117 		_vm->delay(4 * _vm->_tickLength);
1118 	}
1119 
1120 	for (int i = 0; i < 6 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1121 		_screen->copyRegion(120, 30, 120, 110, 64, 42, 2, 2, Screen::CR_NO_P_CHECK);
1122 		_screen->copyRegion((i * 5 + 3) << 3, 72, 144, 120, 48, 32, 4, 2, Screen::CR_NO_P_CHECK);
1123 		_screen->copyRegion(120, 110, 120, 78, 64, 42, 2, 0, Screen::CR_NO_P_CHECK);
1124 		animateCouncil1(2, -1);
1125 		_screen->updateScreen();
1126 		_vm->delay(4 * _vm->_tickLength);
1127 	}
1128 
1129 	for (int i = 0; i < 5 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1130 		animateCouncil2(5, 2, false);
1131 		animateCouncil1(2, -1);
1132 		_screen->updateScreen();
1133 		_vm->delay(4 * _vm->_tickLength);
1134 	}
1135 
1136 	delete[] shp;
1137 }
1138 
inspection()1139 void EoBAmigaFinalePlayer::inspection() {
1140 	if (_vm->shouldQuit() || _vm->skipFlag())
1141 		return;
1142 
1143 	uint8 *shp[5];
1144 	memset(shp, 0, sizeof(shp));
1145 
1146 	_screen->fillRect(0, 170, 319, 186, 31, 0);
1147 	_screen->clearPage(2);
1148 
1149 	_screen->setCurPage(6);
1150 	shp[0] = _screen->encodeShape(0, 0, 8, 40, true);
1151 	_screen->drawShape(2, shp[0], 96, 24, 0, 0);
1152 	_screen->drawShape(2, shp[0], 160, 24, 0, 1);
1153 	delete[] shp[0];
1154 
1155 	_screen->fillRect(0, 48, 9, 120, 31, 0);
1156 	_screen->fillRect(312, 48, 319, 120, 31, 0);
1157 
1158 	_vm->boxMorphTransition(18, 6, 12, 3, 12, 3, 16, 5, 1, 5, 39, 10, 31);
1159 
1160 	for (int i = 0; i < 5; ++i)
1161 		shp[i] = _screen->encodeShape((i << 2) + 8, 0, 4, 24, true);
1162 
1163 	_vm->delay(10 * _vm->_tickLength);
1164 
1165 	for (int i = 2; i < 81 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1166 		_screen->copyRegion(192, 56, 96, 160 - i, 128, i, 6, 0, Screen::CR_NO_P_CHECK);
1167 		_screen->updateScreen();
1168 		_vm->delay(_vm->_tickLength);
1169 		if (i == 40)
1170 			playDialogue(5, false);
1171 	}
1172 
1173 	for (int i = 0; _eyesAnimData[i] != 0xFF && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1174 		if (_eyesAnimData[i] == 15 || _eyesAnimData[i] == 40) {
1175 			_vm->delay(_eyesAnimData[i] * _vm->_tickLength);
1176 			continue;
1177 		}
1178 
1179 		_screen->drawShape(2, shp[_eyesAnimData[i]], 112, 32, 0, 0);
1180 		_screen->drawShape(2, shp[_eyesAnimData[i]], 176, 32, 0, 1);
1181 		_screen->copyRegion(112, 32, 112, 32, 96, 24, 2, 0, Screen::CR_NO_P_CHECK);
1182 		_screen->updateScreen();
1183 
1184 		_vm->delay(_vm->_tickLength);
1185 	}
1186 
1187 	for (int i = 0; i < 5; ++i)
1188 		delete[] shp[i];
1189 }
1190 
surprise()1191 void EoBAmigaFinalePlayer::surprise() {
1192 	if (_vm->shouldQuit() || _vm->skipFlag())
1193 		return;
1194 
1195 	_screen->copyRegion(0, 0, 0, 0, 320, 72, 4, 2, Screen::CR_NO_P_CHECK);
1196 	_screen->copyRegion(0, 0, 0, 80, 320, 72, 2, 2, Screen::CR_NO_P_CHECK);
1197 	_screen->copyRegion(224, 96, 144, 144, 40, 8, 4, 2, Screen::CR_NO_P_CHECK);
1198 
1199 	for (int i = 0; i < 4; ++i) {
1200 		const uint8 *crds = &_councilAnimData4[i * 6];
1201 		_screen->copyRegion(crds[0] << 3, crds[1], crds[4] << 3, crds[5], crds[2] << 3, crds[3], 4, 2, Screen::CR_NO_P_CHECK);
1202 	}
1203 
1204 	_vm->boxMorphTransition(0, 9, 0, 6, 0, 10, 40, 9, 12, 3, 16, 21, 31);
1205 
1206 	for (int i = 0; i < 15 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1207 		animateCouncil1(4, 2);
1208 		animateCouncil2(6, -1, false);
1209 		_screen->updateScreen();
1210 		_vm->delay(4 * _vm->_tickLength);
1211 	}
1212 
1213 	animateCouncil2(98, 2, true);
1214 	_vm->delay(10 * _vm->_tickLength);
1215 	playDialogue(6, true);
1216 	_vm->delay(60 * _vm->_tickLength);
1217 
1218 	_screen->fadeToBlack(16);
1219 	_screen->clearPage(0);
1220 }
1221 
congratulation()1222 void EoBAmigaFinalePlayer::congratulation() {
1223 	if (_vm->shouldQuit() || _vm->skipFlag())
1224 		return;
1225 
1226 	uint8 *shp[3];
1227 	memset(shp, 0, sizeof(shp));
1228 
1229 	_screen->setCurPage(6);
1230 	shp[0] = _screen->encodeShape(12, 24, 12, 64, true);
1231 	shp[1] = _screen->encodeShape(12, 88, 12, 72, true);
1232 	shp[2] = _screen->encodeShape(24, 136, 15, 64, true);
1233 
1234 	_screen->clearPage(2);
1235 	_screen->fadeFromBlack(1);
1236 
1237 	playDialogue(7, false);
1238 
1239 	for (int i = 1; i < 13 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1240 		_screen->copyRegion((12 - i) << 3, 40, (26 - i) << 3, 24, i << 3, 120, 6, 0, Screen::CR_NO_P_CHECK);
1241 		_screen->updateScreen();
1242 		_vm->delay(2 * _vm->_tickLength);
1243 	}
1244 
1245 	_vm->delay(75 * _vm->_tickLength);
1246 	_screen->fadeToBlack(32);
1247 	_screen->clearPage(0);
1248 	_screen->fadeFromBlack(1);
1249 
1250 	for (int i = 0; i < 10 && !_vm->skipFlag() && !_vm->shouldQuit(); i += 2) {
1251 		_screen->drawShape(2, shp[0], _handsAnimData[i], _handsAnimData[i + 1], 0);
1252 		_screen->copyRegion(0, 50, 0, 50, 320, 90, 2, 0, Screen::CR_NO_P_CHECK);
1253 		_screen->clearPage(2);
1254 		_screen->updateScreen();
1255 		_vm->delay(_vm->_tickLength);
1256 	}
1257 
1258 	playDialogue(8, false);
1259 	_screen->updateScreen();
1260 	_vm->delay(50 * _vm->_tickLength);
1261 
1262 	for (int i = 10; i < 18 && !_vm->skipFlag() && !_vm->shouldQuit(); i += 2) {
1263 		_screen->drawShape(2, shp[1], _handsAnimData[i], _handsAnimData[i + 1], 0);
1264 		_screen->drawShape(2, shp[0], _handsAnimData[8], _handsAnimData[9], 0);
1265 		_screen->copyRegion(0, 50, 0, 50, 320, 90, 2, 0, Screen::CR_NO_P_CHECK);
1266 		_screen->clearPage(2);
1267 		_screen->updateScreen();
1268 		_vm->delay(_vm->_tickLength);
1269 	}
1270 
1271 	for (int i = 18; i < 24 && !_vm->skipFlag() && !_vm->shouldQuit(); i += 2) {
1272 		_screen->drawShape(2, shp[2], _handsAnimData[i], _handsAnimData[i + 1], 0);
1273 		_screen->copyRegion(0, 50, 0, 50, 320, 90, 2, 0, Screen::CR_NO_P_CHECK);
1274 		_screen->clearPage(2);
1275 		_screen->updateScreen();
1276 		_vm->delay(2 * _vm->_tickLength);
1277 	}
1278 
1279 	for (int i = 0; i < 3 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1280 		for (int ii = 0; ii < 12 && !_vm->skipFlag() && !_vm->shouldQuit(); ii += 4) {
1281 			_screen->drawShape(2, shp[2], 91, ii + 51, 0);
1282 			_screen->copyRegion(0, 50, 0, 50, 320, 90, 2, 0, Screen::CR_NO_P_CHECK);
1283 			_screen->clearPage(2);
1284 			_screen->updateScreen();
1285 			_vm->delay(25);
1286 		}
1287 		for (int ii = 12; ii > 0 && !_vm->skipFlag() && !_vm->shouldQuit(); ii -= 4) {
1288 			_screen->drawShape(2, shp[2], 91, ii + 51, 0);
1289 			_screen->copyRegion(0, 50, 0, 50, 320, 90, 2, 0, Screen::CR_NO_P_CHECK);
1290 			_screen->clearPage(2);
1291 			_screen->updateScreen();
1292 			_vm->delay(25);
1293 		}
1294 	}
1295 
1296 	for (int i = 0; i < 3; ++i)
1297 		delete[] shp[i];
1298 
1299 	_vm->delay(40 * _vm->_tickLength);
1300 	_screen->fadeToBlack(48);
1301 	_screen->clearPage(0);
1302 	playDialogue(9, false);
1303 	_screen->fadeFromBlack(48);
1304 
1305 	while (!_vm->skipFlag() && !_vm->shouldQuit()) {
1306 		_vm->updateInput();
1307 		_vm->delay(10);
1308 	}
1309 
1310 	_screen->fadeToBlack(48);
1311 }
1312 
animateCouncil1(int numFrames,int skipFrame)1313 void EoBAmigaFinalePlayer::animateCouncil1(int numFrames, int skipFrame) {
1314 	int frame = 5;
1315 	int subFrame = 0;
1316 	int subFrameAlt = 2;
1317 
1318 	if (numFrames == 99) {
1319 		subFrame = _animCurFrame ? 6 : 0;
1320 		_animCurFrame ^= 1;
1321 		const uint8 *crds = &_councilAnimData3[subFrame];
1322 		_screen->copyRegion(crds[0] << 3, crds[1], crds[4] << 3, crds[5], crds[2] << 3, crds[3], 4, 0, Screen::CR_NO_P_CHECK);
1323 
1324 	} else {
1325 		for (int i = 0; i < numFrames; ++i) {
1326 			if (i) {
1327 				frame = _vm->_rnd.getRandomNumberRng(0, 200);
1328 				frame = (frame <= 32) ? frame >> 3 : -1;
1329 				subFrameAlt = 1;
1330 			}
1331 
1332 			if (frame == -1 || frame == skipFrame)
1333 				continue;
1334 
1335 			if (subFrameAlt == _councilAnimData1[frame * 13 + 12]) {
1336 				_councilAnimData1[frame * 13 + 12] = 0;
1337 				subFrame = 6;
1338 			} else {
1339 				_councilAnimData1[frame * 13 + 12]++;
1340 				subFrame = 0;
1341 			}
1342 
1343 			const uint8 *crds = &_councilAnimData1[frame * 13 + subFrame];
1344 			_screen->copyRegion(crds[0] << 3, crds[1], crds[4] << 3, crds[5], crds[2] << 3, crds[3], 4, 0, Screen::CR_NO_P_CHECK);
1345 		}
1346 	}
1347 }
1348 
animateCouncil2(int numFrames,int skipFrame,bool withSpeechAnim)1349 void EoBAmigaFinalePlayer::animateCouncil2(int numFrames, int skipFrame, bool withSpeechAnim) {
1350 	if (numFrames == 98) {
1351 		uint8 frames[6];
1352 		for (int i = 0; i < 6; ++i)
1353 			frames[i] = i;
1354 
1355 		for (int i = 0; i < 6; ++i)
1356 			SWAP(frames[i], frames[_vm->_rnd.getRandomNumberRng(0, 5)]);
1357 
1358 		for (int i = 0; i < 6 && !_vm->skipFlag() && !_vm->shouldQuit(); ++i) {
1359 			if (frames[i] == skipFrame)
1360 				continue;
1361 
1362 			uint8 *crds = &_councilAnimData2[frames[i] * 13];
1363 			crds[12] = 0;
1364 			_screen->copyRegion(crds[0] << 3, crds[1], crds[4] << 3, crds[5], crds[2] << 3, crds[3], 4, 0, Screen::CR_NO_P_CHECK);
1365 
1366 			if (withSpeechAnim)
1367 				animateCouncil1(2, -1);
1368 
1369 			_screen->updateScreen();
1370 			_vm->delay(3 * _vm->_tickLength);
1371 		}
1372 	} else {
1373 		for (int i = 0; i < numFrames; ++i) {
1374 			int frame = _vm->_rnd.getRandomNumberRng(0, 250);
1375 			frame = (frame <= 40) ? frame >> 3 : -1;
1376 
1377 			if (frame == -1 || frame == skipFrame)
1378 				continue;
1379 
1380 			const uint8 *crds = &_councilAnimData2[frame * 13 + _councilAnimData2[frame * 13 + 12] * 6];
1381 			_councilAnimData2[frame * 13 + 12] ^= 1;
1382 			_screen->copyRegion(crds[0] << 3, crds[1], crds[4] << 3, crds[5], crds[2] << 3, crds[3], 4, 0, Screen::CR_NO_P_CHECK);
1383 		}
1384 	}
1385 }
1386 
playDialogue(int line,bool withAnim)1387 void EoBAmigaFinalePlayer::playDialogue(int line, bool withAnim) {
1388 	static const uint8 crds[] = { 0x03, 0x68, 0x05, 0x68 };
1389 	_screen->fillRect(0, 170, 319, 186, 31, 0);
1390 
1391 	if (withAnim) {
1392 		_screen->drawShape(0, _textShapes[line], 0, 170);
1393 		const uint8 *len = &_textFrameDuration[line * 17];
1394 		int offs = 2;
1395 
1396 		for (int i = 0; len[i] != 0x7F && !_vm->skipFlag(); ++i) {
1397 			if (len[i] == 0x7E)
1398 				continue;
1399 			offs ^= 2;
1400 			_screen->copyRegion(crds[offs] << 3, crds[offs + 1], 152, 72, 16, 8, 4, 0, Screen::CR_NO_P_CHECK);
1401 			animateCouncil1(2, 2);
1402 			_screen->updateScreen();
1403 			_vm->delay(len[i] * _vm->_tickLength);
1404 		}
1405 		_screen->copyRegion(crds[2] << 3, crds[3], 152, 72, 16, 8, 4, 0, Screen::CR_NO_P_CHECK);
1406 
1407 	} else {
1408 		_screen->drawShape(0, _textShapes[line], 0, line == 9 ? 92 : 170);
1409 	}
1410 }
1411 
mainMenu()1412 int EoBEngine::mainMenu() {
1413 	int menuChoice = _menuChoiceInit;
1414 	_menuChoiceInit = 0;
1415 
1416 	Screen::FontId of = _screen->_currentFont;
1417 
1418 	while (menuChoice >= 0 && !shouldQuit()) {
1419 		switch (menuChoice) {
1420 		case 0: {
1421 			if (_flags.platform == Common::kPlatformAmiga) {
1422 				_screen->fadeToBlack(10);
1423 				_screen->loadEoBBitmap("TITLE", 0, 5, 3, 1);
1424 				_screen->fadeFromBlack(10);
1425 			} else {
1426 				if (_configRenderMode != Common::kRenderEGA)
1427 					_screen->loadPalette("EOBPAL.COL", _screen->getPalette(0));
1428 				_screen->loadEoBBitmap("INTRO", _cgaMappingDefault, 5, 3, 2);
1429 				_screen->setScreenPalette(_screen->getPalette(0));
1430 			}
1431 
1432 			_screen->_curPage = 2;
1433 			of = _screen->setFont(Screen::FID_6_FNT);
1434 			Common::String versionString(Common::String::format("ScummVM %s", gScummVMVersion));
1435 			_screen->printText(versionString.c_str(), 280 - versionString.size() * 6, 153, _screen->getPagePixel(2, 0, 0), 0);
1436 			_screen->setFont(of);
1437 			_screen->fillRect(0, 159, 319, 199, _screen->getPagePixel(2, 0, 0));
1438 
1439 			if (_flags.platform == Common::kPlatformAmiga) {
1440 				gui_drawBox(75, 165, 177, 29, 22, 28, -1);
1441 				gui_drawBox(74, 164, 179, 31, 22, 28, -1);
1442 			} else {
1443 				gui_drawBox(77, 165, 173, 29, 14, 13, 12);
1444 				gui_drawBox(76, 164, 175, 31, 14, 13, -1);
1445 			}
1446 
1447 			_screen->_curPage = 0;
1448 			_screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
1449 			_screen->updateScreen();
1450 
1451 			_allowImport = true;
1452 			menuChoice = mainMenuLoop();
1453 			_allowImport = false;
1454 			}
1455 
1456 			break;
1457 
1458 		case 1:
1459 			// load game in progress
1460 			menuChoice = -1;
1461 			break;
1462 
1463 		case 2:
1464 			// create new party
1465 			menuChoice = -2;
1466 			break;
1467 
1468 		case 3:
1469 			// quit
1470 			menuChoice = -5;
1471 			break;
1472 
1473 		case 4:
1474 			// intro
1475 			_sound->selectAudioResourceSet(kMusicIntro);
1476 			_sound->loadSoundFile(0);
1477 			_screen->hideMouse();
1478 
1479 			seq_playIntro();
1480 
1481 			_screen->showMouse();
1482 			_sound->selectAudioResourceSet(kMusicIngame);
1483 			_sound->loadSoundFile(0);
1484 
1485 			menuChoice = 0;
1486 			break;
1487 		}
1488 	}
1489 
1490 	return shouldQuit() ? -5 : menuChoice;
1491 }
1492 
mainMenuLoop()1493 int EoBEngine::mainMenuLoop() {
1494 	int sel = -1;
1495 	do {
1496 		_screen->setScreenDim(28);
1497 		_gui->simpleMenu_setup(8, 0, _mainMenuStrings, -1, 0, 0);
1498 
1499 		while (sel == -1 && !shouldQuit())
1500 			sel = _gui->simpleMenu_process(8, _mainMenuStrings, 0, -1, 0);
1501 	} while ((sel < 0 || sel > 5) && !shouldQuit());
1502 
1503 	return sel + 1;
1504 }
1505 
seq_playIntro()1506 void EoBEngine::seq_playIntro() {
1507 	EoBIntroPlayer(this, _screen).start();
1508 }
1509 
seq_playFinale()1510 void EoBEngine::seq_playFinale() {
1511 	Common::SeekableReadStream *s = _res->createReadStream("TEXT.DAT");
1512 	_screen->loadFileDataToPage(s, 5, 32000);
1513 	delete s;
1514 
1515 	snd_playSoundEffect(20);
1516 
1517 	_txt->resetPageBreakString();
1518 	_txt->setWaitButtonMode(1);
1519 	_txt->setupField(12, true);
1520 	gui_drawBox(0, 0, 176, 175, guiSettings()->colors.frame1, guiSettings()->colors.frame2, guiSettings()->colors.fill);
1521 	_txt->printDialogueText(51, _moreStrings[0]);
1522 
1523 	if (checkScriptFlags(0x1FFE)) {
1524 		_txt->printDialogueText(_finBonusStrings[0]);
1525 		for (int i = 0; i < 6; i++) {
1526 			_txt->printDialogueText(_finBonusStrings[1]);
1527 			if (_characters[i].flags & 1)
1528 				_txt->printDialogueText(_characters[i].name);
1529 		}
1530 
1531 		uint32 password = 0;
1532 		for (int i = 0; i < 4; i++) {
1533 			if (!(_characters[i].flags & 1))
1534 				continue;
1535 
1536 			int len = strlen(_characters[i].name);
1537 			for (int ii = 0; ii < len; ii++) {
1538 				uint32 c = _characters[i].name[ii];
1539 				password += (c * c);
1540 			}
1541 		}
1542 
1543 		_txt->printDialogueText(Common::String::format(_finBonusStrings[2], password).c_str(), true);
1544 	}
1545 
1546 	_screen->fadeToBlack();
1547 
1548 	if (_flags.platform == Common::kPlatformAmiga)
1549 		EoBAmigaFinalePlayer(this, _screen).start();
1550 }
1551 
seq_xdeath()1552 void EoBEngine::seq_xdeath() {
1553 	uint8 *shapes1[5];
1554 	uint8 *shapes2;
1555 
1556 	_screen->loadShapeSetBitmap("XDEATH2", 5, 3);
1557 	for (int i = 0; i < 4; i++)
1558 		shapes1[i] = _screen->encodeShape(i / 2 * 14, i / 2 * 88, 14, 88, true, _cgaMappingDefault);
1559 	_screen->loadShapeSetBitmap("XDEATH3", 5, 3);
1560 	shapes2 = _screen->encodeShape(22, 0, 16, 95, true, _cgaMappingDefault);
1561 	_screen->loadEoBBitmap("XDEATH1", _cgaMappingDefault, 5, 3, -1);
1562 	_screen->convertPage(3, 2, _cgaMappingDefault);
1563 	_screen->setCurPage(0);
1564 
1565 	for (int i = 0; i < 10; i++) {
1566 		if (i == 2)
1567 			snd_playSoundEffect(72);
1568 		else if (i == 4 || i == 6)
1569 			snd_playSoundEffect(54);
1570 		else
1571 			snd_playSoundEffect(34);
1572 
1573 		if (i < 6) {
1574 			_screen->copyRegion((i % 3) * 104, i / 3 * 88, 32, 10, 104, 88, 2, 0, Screen::CR_NO_P_CHECK);
1575 		} else {
1576 			snd_playSoundEffect(42);
1577 			_screen->drawShape(0, shapes1[i - 6], 32, 10, 0);
1578 		}
1579 
1580 		_screen->updateScreen();
1581 		delay(4 * _tickLength);
1582 	}
1583 
1584 	const ScreenDim *dm = _screen->getScreenDim(5);
1585 	_screen->modifyScreenDim(5, dm->sx, 8, dm->w, dm->h);
1586 	_screen->copyRegion(0, 0, 0, 0, 176, 120, 0, 5, Screen::CR_NO_P_CHECK);
1587 
1588 	for (int i = 0; i < 19; i++) {
1589 		snd_playSoundEffect(119);
1590 		_screen->copyRegion(0, 0, 0, 0, 176, 120, 5, 2, Screen::CR_NO_P_CHECK);
1591 		_screen->drawShape(2, shapes2, 24, i * 5 - 90, 5);
1592 		_screen->copyRegion(0, 0, 0, 0, 176, 120, 2, 0, Screen::CR_NO_P_CHECK);
1593 		_screen->updateScreen();
1594 		delay(2 * _tickLength);
1595 	}
1596 
1597 	_screen->modifyScreenDim(5, dm->sx, 0, dm->w, dm->h);
1598 
1599 	snd_playSoundEffect(5);
1600 	delay(60 * _tickLength);
1601 
1602 	for (int i = 0; i < 4; i++)
1603 		delete[] shapes1[i];
1604 	delete[] shapes2;
1605 
1606 	gui_drawPlayField(false);
1607 	gui_drawAllCharPortraitsWithStats();
1608 }
1609 
boxMorphTransition(int targetDestX,int targetDestY,int targetFinalX,int targetFinalY,int targetSrcX,int targetSrcY,int targetFinalW,int targetFinalH,int originX1,int originY1,int originW,int originH,int fillColor)1610 void EoBEngine::boxMorphTransition(int targetDestX, int targetDestY, int targetFinalX, int targetFinalY, int targetSrcX, int targetSrcY, int targetFinalW, int targetFinalH, int originX1, int originY1, int originW, int originH, int fillColor) {
1611 	int originX2 = originX1 + originW;
1612 	int originY2 = originY1 + originH;
1613 	if (originY2 > 21)
1614 		originY2 = 21;
1615 
1616 	if (fillColor != -1) {
1617 		_screen->fillRect(0, 170, 319, 186, fillColor, 0);
1618 		_screen->fillRect(0, 170, 319, 186, fillColor, 2);
1619 	}
1620 
1621 	int w = 1;
1622 	int h = 1;
1623 	for (bool runloop = true; runloop && !shouldQuit() && !skipFlag();) {
1624 		uint32 end = _system->getMillis() + _tickLength;
1625 		_screen->copyRegion(targetSrcX << 3, targetSrcY << 3, targetDestX << 3, targetDestY << 3, w << 3, h << 3, 2, 0, Screen::CR_NO_P_CHECK);
1626 		if (originX1 < targetDestX)
1627 			_screen->copyRegion(312, 0, originX1 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
1628 		if (originY1 < targetDestY)
1629 			_screen->copyRegion(0, 192, 0, originY1 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
1630 		if ((targetFinalX + targetFinalW) <= originX2)
1631 			_screen->copyRegion(312, 0, originX2 << 3, 0, 8, 176, 0, 0, Screen::CR_NO_P_CHECK);
1632 		if ((targetFinalY + targetFinalH) <= originY2)
1633 			_screen->copyRegion(0, 192, 0, originY2 << 3, 320, 8, 0, 0, Screen::CR_NO_P_CHECK);
1634 
1635 		if (!(targetDestX != targetFinalX || targetDestY != targetFinalY || w != targetFinalW || h != targetFinalH || originX1 < targetFinalX || originY1 < targetFinalY || (targetFinalX + targetFinalW) < originX2 || (targetFinalY + targetFinalH) < originY2))
1636 			runloop = false;
1637 
1638 		int v = targetFinalX - targetDestX;
1639 		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
1640 		targetDestX += v;
1641 		v = targetFinalY - targetDestY;
1642 		v = (v < 0) ? -1 : ((v > 0) ? 1 : 0);
1643 		targetDestY += v;
1644 
1645 		if (w != targetFinalW)
1646 			w += 2;
1647 		if (w > targetFinalW)
1648 			w = targetFinalW;
1649 
1650 		if (h != targetFinalH)
1651 			h += 2;
1652 		if (h > targetFinalH)
1653 			h = targetFinalH;
1654 
1655 		if (++originX1 > targetFinalX)
1656 			originX1 = targetFinalX;
1657 
1658 		if (++originY1 > targetFinalY)
1659 			originY1 = targetFinalY;
1660 
1661 		if ((targetFinalX + targetFinalW) < originX2)
1662 			originX2--;
1663 
1664 		if ((targetFinalY + targetFinalH) < originY2)
1665 			originY2--;
1666 
1667 		_screen->updateScreen();
1668 		delayUntil(end);
1669 	}
1670 }
1671 
1672 } // End of namespace Kyra
1673 
1674 #endif // ENABLE_EOB
1675