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