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 "hopkins/anim.h"
24 
25 #include "hopkins/files.h"
26 #include "hopkins/globals.h"
27 #include "hopkins/graphics.h"
28 #include "hopkins/hopkins.h"
29 
30 #include "common/system.h"
31 #include "graphics/palette.h"
32 #include "common/file.h"
33 #include "common/rect.h"
34 #include "engines/util.h"
35 
36 namespace Hopkins {
37 
AnimationManager(HopkinsEngine * vm)38 AnimationManager::AnimationManager(HopkinsEngine *vm) {
39 	_vm = vm;
40 	_clearAnimationFl = false;
41 	for (int i = 0; i < 8; ++i)
42 		Common::fill((byte *)&Bank[i], (byte *)&Bank[i] + sizeof(BankItem), 0);
43 	for (int i = 0; i < 35; ++i)
44 		Common::fill((byte *)&_animBqe[i], (byte *)&_animBqe[i] + sizeof(BqeAnimItem), 0);
45 }
46 
clearAll()47 void AnimationManager::clearAll() {
48 	initAnimBqe();
49 }
50 
51 /**
52  * Play Animation
53  * @param filename		Filename of animation to play
54  * @param rate1			Delay amount before starting animation
55  * @param rate2			Delay amount between animation frames
56  * @param rate3			Delay amount after animation finishes
57  */
playAnim(const Common::String & hiresName,const Common::String & lowresName,uint32 rate1,uint32 rate2,uint32 rate3,bool skipSeqFl)58 void AnimationManager::playAnim(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) {
59 	Common::File f;
60 
61 	if (_vm->shouldQuit())
62 		return;
63 
64 	_vm->_events->mouseOff();
65 
66 	byte *screenP = _vm->_graphicsMan->_backBuffer;
67 
68 	if (!f.open(hiresName)) {
69 		if (!f.open(lowresName))
70 			error("Files not found: %s - %s", hiresName.c_str(), lowresName.c_str());
71 	}
72 
73 	f.skip(6);
74 	f.read(_vm->_graphicsMan->_palette, 800);
75 	f.skip(4);
76 	size_t nbytes = f.readUint32LE();
77 	f.skip(14);
78 	f.read(screenP, nbytes);
79 
80 	if (_clearAnimationFl)
81 		_vm->_graphicsMan->clearScreen();
82 
83 	if (skipSeqFl) {
84 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
85 	} else {
86 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
87 		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
88 		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
89 		_vm->_graphicsMan->updateScreen();
90 	}
91 	_vm->_events->_rateCounter = 0;
92 	_vm->_events->_escKeyFl = false;
93 	_vm->_soundMan->loadAnimSound();
94 
95 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
96 		// Do pre-animation delay
97 		do {
98 			if (_vm->_events->_escKeyFl)
99 				break;
100 
101 			_vm->_events->refreshEvents();
102 		} while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate1);
103 	}
104 
105 	if (!_vm->_events->_escKeyFl) {
106 		_vm->_events->_rateCounter = 0;
107 		int frameNumber = 0;
108 		while (!_vm->shouldQuit()) {
109 			++frameNumber;
110 			_vm->_soundMan->playAnimSound(frameNumber);
111 
112 			byte imageStr[17];
113 			// Read frame header
114 			if (f.read(imageStr, 16) != 16)
115 				break;
116 			imageStr[16] = 0;
117 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
118 				break;
119 
120 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
121 
122 			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
123 				do {
124 					if (_vm->_events->_escKeyFl)
125 						break;
126 
127 					_vm->_events->refreshEvents();
128 					_vm->_soundMan->checkSoundEnd();
129 				} while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate2);
130 			}
131 
132 			if (!_vm->_events->_escKeyFl) {
133 				_vm->_events->_rateCounter = 0;
134 				if (*screenP != kByteStop)
135 					_vm->_graphicsMan->copyVideoVbe16(screenP);
136 
137 				_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
138 				_vm->_graphicsMan->updateScreen();
139 				_vm->_soundMan->checkSoundEnd();
140 			}
141 		}
142 	}
143 
144 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE && !_vm->_events->_escKeyFl) {
145 		// Do post-animation delay
146 		do {
147 			if (_vm->_events->_escKeyFl)
148 				break;
149 
150 			_vm->_events->refreshEvents();
151 			_vm->_soundMan->checkSoundEnd();
152 		} while (_vm->_events->_rateCounter < rate3);
153 	}
154 
155 	if (!_vm->_events->_escKeyFl) {
156 		_vm->_events->_rateCounter = 0;
157 		_vm->_soundMan->checkSoundEnd();
158 	}
159 
160 	if (_vm->_graphicsMan->_fadingFl) {
161 		byte *screenCopy = _vm->_globals->allocMemory(307200);
162 
163 		f.seek(6);
164 		f.read(_vm->_graphicsMan->_palette, 800);
165 		f.skip(4);
166 		nbytes = f.readUint32LE();
167 		f.skip(14);
168 		f.read(screenP, nbytes);
169 
170 		memcpy(screenCopy, screenP, 307200);
171 
172 		for (;;) {
173 			byte imageStr[17];
174 			if (f.read(imageStr, 16) != 16)
175 				break;
176 			imageStr[16] = 0;
177 
178 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
179 				break;
180 
181 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
182 			if (*screenP != kByteStop)
183 				_vm->_graphicsMan->copyWinscanVbe3(screenP, screenCopy);
184 		}
185 		_vm->_graphicsMan->fadeOutDefaultLength(screenCopy);
186 		_vm->_globals->freeMemory(screenCopy);
187 	}
188 
189 	_vm->_graphicsMan->_fadingFl = false;
190 	f.close();
191 	_vm->_graphicsMan->_skipVideoLockFl = false;
192 
193 	_vm->_events->mouseOn();
194 }
195 
196 /**
197  * Play Animation, type 2
198  */
playAnim2(const Common::String & hiresName,const Common::String & lowresName,uint32 rate1,uint32 rate2,uint32 rate3)199 void AnimationManager::playAnim2(const Common::String &hiresName, const Common::String &lowresName, uint32 rate1, uint32 rate2, uint32 rate3) {
200 	int oldScrollPosX = 0;
201 	byte *screenP = NULL;
202 	Common::File f;
203 
204 	if (_vm->shouldQuit())
205 		return;
206 
207 	_vm->_events->mouseOff();
208 
209 	while (!_vm->shouldQuit()) {
210 		memcpy(_vm->_graphicsMan->_oldPalette, _vm->_graphicsMan->_palette, 769);
211 
212 		_vm->_graphicsMan->backupScreen();
213 
214 		if (!_vm->_graphicsMan->_lineNbr)
215 			_vm->_graphicsMan->_scrollOffset = 0;
216 
217 		screenP = _vm->_graphicsMan->_backBuffer;
218 		if (!f.open(hiresName)) {
219 			if (!f.open(lowresName))
220 				error("Error opening files: %s - %s", hiresName.c_str(), lowresName.c_str());
221 		}
222 
223 		f.skip(6);
224 		f.read(_vm->_graphicsMan->_palette, 800);
225 		f.skip(4);
226 		size_t nbytes = f.readUint32LE();
227 		f.skip(14);
228 
229 		f.read(screenP, nbytes);
230 
231 		_vm->_graphicsMan->clearPalette();
232 		oldScrollPosX = _vm->_graphicsMan->_scrollPosX;
233 		_vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH);
234 		_vm->_graphicsMan->scrollScreen(0);
235 		_vm->_graphicsMan->clearScreen();
236 		_vm->_graphicsMan->_maxX = SCREEN_WIDTH;
237 
238 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
239 		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
240 		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
241 		_vm->_graphicsMan->updateScreen();
242 
243 		_vm->_events->_rateCounter = 0;
244 		_vm->_events->_escKeyFl = false;
245 		_vm->_soundMan->loadAnimSound();
246 		if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
247 			while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1) {
248 				_vm->_events->refreshEvents();
249 			}
250 		}
251 		break;
252 	}
253 
254 	if (!_vm->_events->_escKeyFl) {
255 		_vm->_events->_rateCounter = 0;
256 		int frameNumber = 0;
257 		for (;;) {
258 			if (_vm->_events->_escKeyFl)
259 				break;
260 			++frameNumber;
261 			_vm->_soundMan->playAnimSound(frameNumber);
262 			byte imageStr[17];
263 			if (f.read(imageStr, 16) != 16)
264 				break;
265 			imageStr[16] = 0;
266 
267 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
268 				break;
269 
270 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
271 			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
272 				while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2) {
273 					_vm->_events->refreshEvents();
274 					_vm->_soundMan->checkSoundEnd();
275 				}
276 			}
277 
278 			_vm->_events->_rateCounter = 0;
279 			if (*screenP != kByteStop)
280 				_vm->_graphicsMan->copyVideoVbe16(screenP);
281 
282 			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
283 			_vm->_graphicsMan->updateScreen();
284 			_vm->_soundMan->checkSoundEnd();
285 		}
286 
287 		if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
288 			while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3) {
289 				_vm->_events->refreshEvents();
290 				_vm->_soundMan->checkSoundEnd();
291 			}
292 		}
293 	}
294 
295 	_vm->_graphicsMan->_skipVideoLockFl = false;
296 	f.close();
297 
298 	if (_vm->_graphicsMan->_fadingFl) {
299 		f.seek(6);
300 		f.read(_vm->_graphicsMan->_palette, 800);
301 		f.skip(4);
302 		size_t nbytes = f.readUint32LE();
303 		f.skip(14);
304 		f.read(screenP, nbytes);
305 		byte *ptra = _vm->_globals->allocMemory(307200);
306 		memcpy(ptra, screenP, 307200);
307 
308 		for (;;) {
309 			byte imageStr[17];
310 			if (f.read(imageStr, 16) != 16)
311 				break;
312 			imageStr[16] = 0;
313 
314 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
315 				break;
316 
317 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
318 			if (*screenP != kByteStop)
319 				_vm->_graphicsMan->copyWinscanVbe3(screenP, ptra);
320 		}
321 		_vm->_graphicsMan->fadeOutDefaultLength(ptra);
322 		ptra = _vm->_globals->freeMemory(ptra);
323 	}
324 	_vm->_graphicsMan->_fadingFl = false;
325 
326 	_vm->_graphicsMan->restoreScreen();
327 
328 	memcpy(_vm->_graphicsMan->_palette, _vm->_graphicsMan->_oldPalette, 769);
329 	_vm->_graphicsMan->clearPalette();
330 	_vm->_graphicsMan->clearScreen();
331 
332 	_vm->_graphicsMan->_scrollPosX = oldScrollPosX;
333 	_vm->_graphicsMan->scrollScreen(oldScrollPosX);
334 	if (_vm->_graphicsMan->_largeScreenFl) {
335 		_vm->_graphicsMan->setScreenWidth(2 * SCREEN_WIDTH);
336 		_vm->_graphicsMan->_maxX = 2 * SCREEN_WIDTH;
337 		_vm->_graphicsMan->display8BitRect(_vm->_graphicsMan->_frontBuffer, _vm->_events->_startPos.x, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
338 	} else {
339 		_vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH);
340 		_vm->_graphicsMan->_maxX = SCREEN_WIDTH;
341 		_vm->_graphicsMan->clearScreen();
342 		_vm->_graphicsMan->display8BitRect(_vm->_graphicsMan->_frontBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
343 	}
344 	_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
345 
346 	_vm->_graphicsMan->fadeInShort();
347 	_vm->_graphicsMan->updateScreen();
348 
349 	_vm->_events->mouseOn();
350 }
351 
352 /**
353  * Load Animation
354  */
loadAnim(const Common::String & animName)355 void AnimationManager::loadAnim(const Common::String &animName) {
356 	clearAnim();
357 
358 	Common::String filename = animName + ".ANI";
359 	Common::File f;
360 	if (!f.open(filename))
361 		error("Failed to open %s", filename.c_str());
362 
363 	int filesize = f.size();
364 	int nbytes = filesize - 115;
365 
366 	char header[10];
367 	char dummyBuf[15];
368 	char filename1[15];
369 	char filename2[15];
370 	char filename3[15];
371 	char filename4[15];
372 	char filename5[15];
373 	char filename6[15];
374 
375 	f.read(header, 10);
376 	f.read(dummyBuf, 15);
377 	f.read(filename1, 15);
378 	f.read(filename2, 15);
379 	f.read(filename3, 15);
380 	f.read(filename4, 15);
381 	f.read(filename5, 15);
382 	f.read(filename6, 15);
383 
384 	if (READ_BE_UINT32(header) != MKTAG('A', 'N', 'I', 'S'))
385 		error("Invalid animation File: %s", filename.c_str());
386 
387 	const char *files[6] = { &filename1[0], &filename2[0], &filename3[0], &filename4[0],
388 			&filename5[0], &filename6[0] };
389 
390 	for (int idx = 0; idx <= 5; ++idx) {
391 		if (files[idx][0]) {
392 			if (!f.exists(files[idx]))
393 				error("Missing file %s in animation File: %s", files[idx], filename.c_str());
394 			if (loadSpriteBank(idx + 1, files[idx]))
395 				error("Invalid sprite bank in animation File: %s", filename.c_str());
396 		}
397 	}
398 
399 	byte *data = _vm->_globals->allocMemory(nbytes + 1);
400 	f.read(data, nbytes);
401 	f.close();
402 
403 	for (int idx = 1; idx <= 20; ++idx)
404 		searchAnim(data, idx, nbytes);
405 
406 	_vm->_globals->freeMemory(data);
407 }
408 
409 /**
410  * Clear animation
411  */
clearAnim()412 void AnimationManager::clearAnim() {
413 	for (int idx = 0; idx < 35; ++idx) {
414 		_animBqe[idx]._data = _vm->_globals->freeMemory(_animBqe[idx]._data);
415 		_animBqe[idx]._enabledFl = false;
416 	}
417 
418 	for (int idx = 0; idx < 8; ++idx) {
419 		Bank[idx]._data = _vm->_globals->freeMemory(Bank[idx]._data);
420 		Bank[idx]._loadedFl = false;
421 		Bank[idx]._filename = "";
422 		Bank[idx]._fileHeader = 0;
423 	}
424 }
425 
426 /**
427  * Load Sprite Bank
428  */
loadSpriteBank(int idx,const Common::String & filename)429 int AnimationManager::loadSpriteBank(int idx, const Common::String &filename) {
430 	int result = 0;
431 	Bank[idx]._loadedFl = true;
432 	Bank[idx]._filename = filename;
433 
434 	byte *fileDataPtr = _vm->_fileIO->loadFile(filename);
435 
436 	Bank[idx]._fileHeader = 0;
437 	if (fileDataPtr[1] == 'L' && fileDataPtr[2] == 'E')
438 		Bank[idx]._fileHeader = 1;
439 	else if (fileDataPtr[1] == 'O' && fileDataPtr[2] == 'R')
440 		Bank[idx]._fileHeader = 2;
441 
442 	if (!Bank[idx]._fileHeader) {
443 		_vm->_globals->freeMemory(fileDataPtr);
444 		Bank[idx]._loadedFl = false;
445 		result = -1;
446 	}
447 
448 	Bank[idx]._data = fileDataPtr;
449 
450 	int objectDataIdx = 0;
451 	for(objectDataIdx = 0; objectDataIdx <= 249; objectDataIdx++) {
452 		int width = _vm->_objectsMan->getWidth(fileDataPtr, objectDataIdx);
453 		int height = _vm->_objectsMan->getHeight(fileDataPtr, objectDataIdx);
454 		if (!width && !height)
455 			break;
456 	}
457 
458 	if (objectDataIdx > 249) {
459 		_vm->_globals->freeMemory(fileDataPtr);
460 		Bank[idx]._loadedFl = false;
461 		result = -2;
462 	}
463 	Bank[idx]._objDataIdx = objectDataIdx;
464 
465 	Common::String ofsFilename = Bank[idx]._filename;
466 	char ch;
467 	do {
468 		ch = ofsFilename.lastChar();
469 		ofsFilename.deleteLastChar();
470 	} while (ch != '.');
471 	ofsFilename += ".OFS";
472 
473 	Common::File f;
474 	if (f.exists(ofsFilename)) {
475 		byte *ofsData = _vm->_fileIO->loadFile(ofsFilename);
476 		byte *curOfsData = ofsData;
477 		for (int objIdx = 0; objIdx < Bank[idx]._objDataIdx; ++objIdx, curOfsData += 8) {
478 			int x1 = READ_LE_INT16(curOfsData);
479 			int y1 = READ_LE_INT16(curOfsData + 2);
480 			int x2 = READ_LE_INT16(curOfsData + 4);
481 			int y2 = READ_LE_INT16(curOfsData + 6);
482 
483 			_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x1, y1, 0);
484 			if (Bank[idx]._fileHeader == 2)
485 				_vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x2, y2, 1);
486 		}
487 
488 		_vm->_globals->freeMemory(ofsData);
489 		result = 0;
490 	}
491 
492 	return result;
493 }
494 
495 /**
496  * Search Animation
497  */
searchAnim(const byte * data,int animIndex,int bufSize)498 void AnimationManager::searchAnim(const byte *data, int animIndex, int bufSize) {
499 	for (int dataIdx = 0; dataIdx <= bufSize; dataIdx++) {
500 		if (READ_BE_UINT32(&data[dataIdx]) == MKTAG('A', 'N', 'I', 'M')) {
501 			int entryIndex = data[dataIdx + 4];
502 			if (animIndex == entryIndex) {
503 				int curBufferPos = dataIdx + 5;
504 				int count = 0;
505 				bool innerLoopCond = false;
506 				do {
507 					if (READ_BE_UINT32(&data[curBufferPos]) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(&data[curBufferPos]) == MKTAG24('F', 'I', 'N'))
508 						innerLoopCond = true;
509 					if (bufSize < curBufferPos) {
510 						_animBqe[animIndex]._enabledFl = false;
511 						_animBqe[animIndex]._data = NULL;
512 						return;
513 					}
514 					++curBufferPos;
515 					++count;
516 				} while (!innerLoopCond);
517 				_animBqe[animIndex]._data = _vm->_globals->allocMemory(count + 50);
518 				_animBqe[animIndex]._enabledFl = true;
519 				memcpy(_animBqe[animIndex]._data, data + dataIdx + 5, 20);
520 
521 				byte *dataP = _animBqe[animIndex]._data;
522 				int curDestDataIndx = 20;
523 				int curSrcDataIndx = dataIdx + 25;
524 
525 				for (int i = 0; i <= 4999; i++) {
526 					memcpy(dataP + curDestDataIndx, data + curSrcDataIndx, 10);
527 					if (!READ_LE_UINT16(data + curSrcDataIndx + 4))
528 						break;
529 					curDestDataIndx += 10;
530 					curSrcDataIndx += 10;
531 				}
532 				break;
533 			}
534 		}
535 		if (READ_BE_UINT24(&data[dataIdx]) == MKTAG24('F', 'I', 'N'))
536 			break;
537 	}
538 }
539 
540 /**
541  * Play sequence
542  */
playSequence(const Common::String & file,uint32 rate1,uint32 rate2,uint32 rate3,bool skipEscFl,bool skipSeqFl,bool noColFl)543 void AnimationManager::playSequence(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipEscFl, bool skipSeqFl, bool noColFl) {
544 	if (_vm->shouldQuit())
545 		return;
546 
547 	_vm->_events->_mouseFl = false;
548 	if (!noColFl) {
549 		_vm->_events->refreshScreenAndEvents();
550 
551 		_vm->_graphicsMan->backupScreen();
552 
553 		if (!_vm->_graphicsMan->_lineNbr)
554 			_vm->_graphicsMan->_scrollOffset = 0;
555 	}
556 	byte *screenP = _vm->_graphicsMan->_backBuffer;
557 	Common::File f;
558 	if (!f.open(file))
559 		error("Error opening file - %s", file.c_str());
560 
561 	f.skip(6);
562 	f.read(_vm->_graphicsMan->_palette, 800);
563 	f.skip(4);
564 	size_t nbytes = f.readUint32LE();
565 	f.skip(14);
566 	f.read(screenP, nbytes);
567 
568 	if (skipSeqFl) {
569 		if (!_vm->getIsDemo()) {
570 			_vm->_graphicsMan->setColorPercentage(252, 100, 100, 100);
571 			_vm->_graphicsMan->setColorPercentage(253, 100, 100, 100);
572 			_vm->_graphicsMan->setColorPercentage(251, 100, 100, 100);
573 			_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
574 		}
575 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
576 	} else {
577 		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
578 		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
579 		_vm->_graphicsMan->updateScreen();
580 	}
581 	bool skipFl = false;
582 	if (noColFl)
583 		_vm->_graphicsMan->fadeInDefaultLength(screenP);
584 	_vm->_events->_rateCounter = 0;
585 	_vm->_events->_escKeyFl = false;
586 	_vm->_soundMan->loadAnimSound();
587 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
588 		do {
589 			if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
590 				skipFl = true;
591 				break;
592 			}
593 
594 			_vm->_events->_escKeyFl = false;
595 			_vm->_events->refreshEvents();
596 			_vm->_soundMan->checkSoundEnd();
597 		} while (_vm->_events->_rateCounter < rate1);
598 	}
599 	_vm->_events->_rateCounter = 0;
600 	if (!skipFl) {
601 		int soundNumber = 0;
602 		for (;;) {
603 			++soundNumber;
604 			_vm->_soundMan->playAnimSound(soundNumber);
605 			byte imageStr[17];
606 			if (f.read(imageStr, 16) != 16)
607 				break;
608 			imageStr[16] = 0;
609 
610 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
611 				break;
612 
613 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
614 			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
615 				do {
616 					if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
617 						skipFl = true;
618 						break;
619 					}
620 
621 					_vm->_events->_escKeyFl = false;
622 					_vm->_events->refreshEvents();
623 					_vm->_soundMan->checkSoundEnd();
624 				} while (_vm->_events->_rateCounter < rate2);
625 			}
626 
627 			if (skipFl)
628 				break;
629 
630 			_vm->_events->_rateCounter = 0;
631 			if (*screenP != kByteStop)
632 				_vm->_graphicsMan->copyVideoVbe16a(screenP);
633 
634 			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
635 			_vm->_graphicsMan->updateScreen();
636 			_vm->_soundMan->checkSoundEnd();
637 		}
638 	}
639 
640 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE && !skipFl) {
641 		do {
642 			if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
643 				skipFl = true;
644 				break;
645 			}
646 
647 			_vm->_events->_escKeyFl = false;
648 			_vm->_events->refreshEvents();
649 			_vm->_soundMan->checkSoundEnd();
650 		} while (_vm->_events->_rateCounter < rate3);
651 	}
652 
653 	if (!skipFl)
654 		_vm->_events->_rateCounter = 0;
655 
656 	_vm->_graphicsMan->_skipVideoLockFl = false;
657 	f.close();
658 
659 	if (!noColFl) {
660 		_vm->_graphicsMan->restoreScreen();
661 
662 		_vm->_events->_mouseFl = true;
663 	}
664 }
665 
666 /**
667  * Play Sequence type 2
668  */
playSequence2(const Common::String & file,uint32 rate1,uint32 rate2,uint32 rate3,bool skipSeqFl)669 void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) {
670 	byte *screenP;
671 	Common::File f;
672 
673 	if (_vm->shouldQuit())
674 		return;
675 
676 	_vm->_events->_mouseFl = false;
677 	screenP = _vm->_graphicsMan->_backBuffer;
678 
679 	if (!f.open(file))
680 		error("File not found - %s", file.c_str());
681 
682 	f.skip(6);
683 	f.read(_vm->_graphicsMan->_palette, 800);
684 	f.skip(4);
685 	size_t nbytes = f.readUint32LE();
686 	f.skip(14);
687 	f.read(screenP, nbytes);
688 
689 	if (skipSeqFl) {
690 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
691 	} else {
692 		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
693 		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
694 
695 		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
696 		_vm->_graphicsMan->updateScreen();
697 	}
698 	_vm->_events->_rateCounter = 0;
699 	_vm->_events->_escKeyFl = false;
700 	_vm->_soundMan->loadAnimSound();
701 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
702 		do {
703 			_vm->_events->refreshEvents();
704 			_vm->_soundMan->checkSoundEnd();
705 		} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1);
706 	}
707 
708 	if (!_vm->_events->_escKeyFl) {
709 		_vm->_events->_rateCounter = 0;
710 		int frameNumber = 0;
711 		while (!_vm->shouldQuit()) {
712 			_vm->_soundMan->playAnimSound(frameNumber++);
713 
714 			byte imageStr[17];
715 			if (f.read(imageStr, 16) != 16)
716 				break;
717 			imageStr[16] = 0;
718 
719 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
720 				break;
721 
722 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
723 			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
724 				do {
725 					_vm->_events->refreshEvents();
726 				} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2);
727 			}
728 
729 			_vm->_events->_rateCounter = 0;
730 			if (*screenP != kByteStop)
731 				_vm->_graphicsMan->copyVideoVbe16a(screenP);
732 
733 			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
734 			_vm->_graphicsMan->updateScreen();
735 			_vm->_soundMan->checkSoundEnd();
736 		}
737 	}
738 
739 	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
740 		// Wait for third rate delay
741 		do {
742 			_vm->_events->refreshEvents();
743 			_vm->_soundMan->checkSoundEnd();
744 		} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3);
745 	}
746 
747 	_vm->_events->_rateCounter = 0;
748 
749 	if (_vm->_graphicsMan->_fadingFl) {
750 		byte *ptra = _vm->_globals->allocMemory(307200);
751 
752 		f.seek(6);
753 		f.read(_vm->_graphicsMan->_palette, 800);
754 		f.skip(4);
755 		nbytes = f.readUint32LE();
756 		f.skip(14);
757 		f.read(screenP, nbytes);
758 
759 		memcpy(ptra, screenP, 307200);
760 		for (;;) {
761 			byte imageStr[17];
762 			if (f.read(imageStr, 16) != 16)
763 				break;
764 			imageStr[16] = 0;
765 
766 			if (strncmp((const char *)imageStr, "IMAGE=", 6))
767 				break;
768 
769 			f.read(screenP, READ_LE_UINT32(imageStr + 8));
770 			if (*screenP != kByteStop)
771 				_vm->_graphicsMan->copyWinscanVbe(screenP, ptra);
772 		}
773 		_vm->_graphicsMan->fadeOutDefaultLength(ptra);
774 		ptra = _vm->_globals->freeMemory(ptra);
775 	}
776 	_vm->_graphicsMan->_fadingFl = false;
777 
778 	f.close();
779 	_vm->_events->_mouseFl = true;
780 }
781 
initAnimBqe()782 void AnimationManager::initAnimBqe() {
783 	for (int idx = 0; idx < 35; ++idx) {
784 		_animBqe[idx]._data = NULL;
785 		_animBqe[idx]._enabledFl = false;
786 	}
787 
788 	for (int idx = 0; idx < 8; ++idx) {
789 		Bank[idx]._data = NULL;
790 		Bank[idx]._loadedFl = false;
791 		Bank[idx]._filename = "";
792 		Bank[idx]._fileHeader = 0;
793 	}
794 }
795 
796 } // End of namespace Hopkins
797