/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "hopkins/anim.h" #include "hopkins/files.h" #include "hopkins/globals.h" #include "hopkins/graphics.h" #include "hopkins/hopkins.h" #include "common/system.h" #include "graphics/palette.h" #include "common/file.h" #include "common/rect.h" #include "engines/util.h" namespace Hopkins { AnimationManager::AnimationManager(HopkinsEngine *vm) { _vm = vm; _clearAnimationFl = false; for (int i = 0; i < 8; ++i) Common::fill((byte *)&Bank[i], (byte *)&Bank[i] + sizeof(BankItem), 0); for (int i = 0; i < 35; ++i) Common::fill((byte *)&_animBqe[i], (byte *)&_animBqe[i] + sizeof(BqeAnimItem), 0); } void AnimationManager::clearAll() { initAnimBqe(); } /** * Play Animation * @param filename Filename of animation to play * @param rate1 Delay amount before starting animation * @param rate2 Delay amount between animation frames * @param rate3 Delay amount after animation finishes */ void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) { Common::File f; if (_vm->shouldQuit()) return; _vm->_events->mouseOff(); byte *screenP = _vm->_graphicsMan->_backBuffer; Common::String tmpStr; // The Windows 95 demo only contains the interlaced version of the BOMBE1 and BOMBE2 videos if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE1A.ANM") tmpStr = "BOMBE1.ANM"; else if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE2A.ANM") tmpStr = "BOMBE2.ANM"; else tmpStr = filename; if (!f.open(tmpStr)) error("File not found - %s", tmpStr.c_str()); f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); if (_clearAnimationFl) _vm->_graphicsMan->clearScreen(); if (skipSeqFl) { _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); } else { _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); _vm->_graphicsMan->copy16BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); } _vm->_events->_rateCounter = 0; _vm->_events->_escKeyFl = false; _vm->_soundMan->loadAnimSound(); if (_vm->_globals->_eventMode == 1) { // Do pre-animation delay do { if (_vm->_events->_escKeyFl) break; _vm->_events->refreshEvents(); } while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate1); } if (!_vm->_events->_escKeyFl) { _vm->_events->_rateCounter = 0; int frameNumber = 0; while (!_vm->shouldQuit()) { ++frameNumber; _vm->_soundMan->playAnimSound(frameNumber); byte imageStr[17]; // Read frame header if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (_vm->_globals->_eventMode == 1) { do { if (_vm->_events->_escKeyFl) break; _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate2); } if (!_vm->_events->_escKeyFl) { _vm->_events->_rateCounter = 0; if (*screenP != kByteStop) _vm->_graphicsMan->copyVideoVbe16(screenP); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); _vm->_soundMan->checkSoundEnd(); } } } if (_vm->_globals->_eventMode == 1 && !_vm->_events->_escKeyFl) { // Do post-animation delay do { if (_vm->_events->_escKeyFl) break; _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (_vm->_events->_rateCounter < rate3); } if (!_vm->_events->_escKeyFl) { _vm->_events->_rateCounter = 0; _vm->_soundMan->checkSoundEnd(); } if (_vm->_graphicsMan->_fadingFl) { byte *screenCopy = _vm->_globals->allocMemory(307200); f.seek(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); memcpy(screenCopy, screenP, 307200); for (;;) { byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (*screenP != kByteStop) _vm->_graphicsMan->copyWinscanVbe3(screenP, screenCopy); } _vm->_graphicsMan->fadeOutDefaultLength(screenCopy); _vm->_globals->freeMemory(screenCopy); } _vm->_graphicsMan->_fadingFl = false; f.close(); _vm->_graphicsMan->_skipVideoLockFl = false; _vm->_events->mouseOn(); } /** * Play Animation, type 2 */ void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3) { int oldScrollPosX = 0; byte *screenP = NULL; Common::File f; if (_vm->shouldQuit()) return; _vm->_events->mouseOff(); while (!_vm->shouldQuit()) { memcpy(_vm->_graphicsMan->_oldPalette, _vm->_graphicsMan->_palette, 769); _vm->_graphicsMan->backupScreen(); if (!_vm->_graphicsMan->_lineNbr) _vm->_graphicsMan->_scrollOffset = 0; screenP = _vm->_graphicsMan->_backBuffer; if (!f.open(filename)) error("Error opening file - %s", filename.c_str()); f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); _vm->_graphicsMan->clearPalette(); oldScrollPosX = _vm->_graphicsMan->_scrollPosX; _vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH); _vm->_graphicsMan->scrollScreen(0); _vm->_graphicsMan->clearScreen(); _vm->_graphicsMan->_maxX = SCREEN_WIDTH; _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); _vm->_graphicsMan->copy16BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); _vm->_events->_rateCounter = 0; _vm->_events->_escKeyFl = false; _vm->_soundMan->loadAnimSound(); if (_vm->_globals->_eventMode == 1) { while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1) { _vm->_events->refreshEvents(); } } break; } if (!_vm->_events->_escKeyFl) { _vm->_events->_rateCounter = 0; int frameNumber = 0; for (;;) { if (_vm->_events->_escKeyFl) break; ++frameNumber; _vm->_soundMan->playAnimSound(frameNumber); byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (_vm->_globals->_eventMode == 1) { while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2) { _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } } _vm->_events->_rateCounter = 0; if (*screenP != kByteStop) _vm->_graphicsMan->copyVideoVbe16(screenP); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); _vm->_soundMan->checkSoundEnd(); } if (_vm->_globals->_eventMode == 1) { while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3) { _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } } } _vm->_graphicsMan->_skipVideoLockFl = false; f.close(); if (_vm->_graphicsMan->_fadingFl) { f.seek(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); byte *ptra = _vm->_globals->allocMemory(307200); memcpy(ptra, screenP, 307200); for (;;) { byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (*screenP != kByteStop) _vm->_graphicsMan->copyWinscanVbe3(screenP, ptra); } _vm->_graphicsMan->fadeOutDefaultLength(ptra); ptra = _vm->_globals->freeMemory(ptra); } _vm->_graphicsMan->_fadingFl = false; _vm->_graphicsMan->restoreScreen(); memcpy(_vm->_graphicsMan->_palette, _vm->_graphicsMan->_oldPalette, 769); _vm->_graphicsMan->clearPalette(); _vm->_graphicsMan->clearScreen(); _vm->_graphicsMan->_scrollPosX = oldScrollPosX; _vm->_graphicsMan->scrollScreen(oldScrollPosX); if (_vm->_graphicsMan->_largeScreenFl) { _vm->_graphicsMan->setScreenWidth(2 * SCREEN_WIDTH); _vm->_graphicsMan->_maxX = 2 * SCREEN_WIDTH; _vm->_graphicsMan->copy16BitRect(_vm->_graphicsMan->_frontBuffer, _vm->_events->_startPos.x, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); } else { _vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH); _vm->_graphicsMan->_maxX = SCREEN_WIDTH; _vm->_graphicsMan->clearScreen(); _vm->_graphicsMan->copy16BitRect(_vm->_graphicsMan->_frontBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); } _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->fadeInShort(); _vm->_graphicsMan->updateScreen(); _vm->_events->mouseOn(); } /** * Load Animation */ void AnimationManager::loadAnim(const Common::String &animName) { clearAnim(); Common::String filename = animName + ".ANI"; Common::File f; if (!f.open(filename)) error("Failed to open %s", filename.c_str()); int filesize = f.size(); int nbytes = filesize - 115; char header[10]; char dummyBuf[15]; char filename1[15]; char filename2[15]; char filename3[15]; char filename4[15]; char filename5[15]; char filename6[15]; f.read(header, 10); f.read(dummyBuf, 15); f.read(filename1, 15); f.read(filename2, 15); f.read(filename3, 15); f.read(filename4, 15); f.read(filename5, 15); f.read(filename6, 15); if (READ_BE_UINT32(header) != MKTAG('A', 'N', 'I', 'S')) error("Invalid animation File: %s", filename.c_str()); const char *files[6] = { &filename1[0], &filename2[0], &filename3[0], &filename4[0], &filename5[0], &filename6[0] }; for (int idx = 0; idx <= 5; ++idx) { if (files[idx][0]) { if (!f.exists(files[idx])) error("Missing file %s in animation File: %s", files[idx], filename.c_str()); if (loadSpriteBank(idx + 1, files[idx])) error("Invalid sprite bank in animation File: %s", filename.c_str()); } } byte *data = _vm->_globals->allocMemory(nbytes + 1); f.read(data, nbytes); f.close(); for (int idx = 1; idx <= 20; ++idx) searchAnim(data, idx, nbytes); _vm->_globals->freeMemory(data); } /** * Clear animation */ void AnimationManager::clearAnim() { for (int idx = 0; idx < 35; ++idx) { _animBqe[idx]._data = _vm->_globals->freeMemory(_animBqe[idx]._data); _animBqe[idx]._enabledFl = false; } for (int idx = 0; idx < 8; ++idx) { Bank[idx]._data = _vm->_globals->freeMemory(Bank[idx]._data); Bank[idx]._loadedFl = false; Bank[idx]._filename = ""; Bank[idx]._fileHeader = 0; } } /** * Load Sprite Bank */ int AnimationManager::loadSpriteBank(int idx, const Common::String &filename) { int result = 0; Bank[idx]._loadedFl = true; Bank[idx]._filename = filename; byte *fileDataPtr = _vm->_fileIO->loadFile(filename); Bank[idx]._fileHeader = 0; if (fileDataPtr[1] == 'L' && fileDataPtr[2] == 'E') Bank[idx]._fileHeader = 1; else if (fileDataPtr[1] == 'O' && fileDataPtr[2] == 'R') Bank[idx]._fileHeader = 2; if (!Bank[idx]._fileHeader) { _vm->_globals->freeMemory(fileDataPtr); Bank[idx]._loadedFl = false; result = -1; } Bank[idx]._data = fileDataPtr; int objectDataIdx = 0; for(objectDataIdx = 0; objectDataIdx <= 249; objectDataIdx++) { int width = _vm->_objectsMan->getWidth(fileDataPtr, objectDataIdx); int height = _vm->_objectsMan->getHeight(fileDataPtr, objectDataIdx); if (!width && !height) break; } if (objectDataIdx > 249) { _vm->_globals->freeMemory(fileDataPtr); Bank[idx]._loadedFl = false; result = -2; } Bank[idx]._objDataIdx = objectDataIdx; Common::String ofsFilename = Bank[idx]._filename; char ch; do { ch = ofsFilename.lastChar(); ofsFilename.deleteLastChar(); } while (ch != '.'); ofsFilename += ".OFS"; Common::File f; if (f.exists(ofsFilename)) { byte *ofsData = _vm->_fileIO->loadFile(ofsFilename); byte *curOfsData = ofsData; for (int objIdx = 0; objIdx < Bank[idx]._objDataIdx; ++objIdx, curOfsData += 8) { int x1 = READ_LE_INT16(curOfsData); int y1 = READ_LE_INT16(curOfsData + 2); int x2 = READ_LE_INT16(curOfsData + 4); int y2 = READ_LE_INT16(curOfsData + 6); _vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x1, y1, 0); if (Bank[idx]._fileHeader == 2) _vm->_objectsMan->setOffsetXY(Bank[idx]._data, objIdx, x2, y2, 1); } _vm->_globals->freeMemory(ofsData); result = 0; } return result; } /** * Search Animation */ void AnimationManager::searchAnim(const byte *data, int animIndex, int bufSize) { for (int dataIdx = 0; dataIdx <= bufSize; dataIdx++) { if (READ_BE_UINT32(&data[dataIdx]) == MKTAG('A', 'N', 'I', 'M')) { int entryIndex = data[dataIdx + 4]; if (animIndex == entryIndex) { int curBufferPos = dataIdx + 5; int count = 0; bool innerLoopCond = false; do { if (READ_BE_UINT32(&data[curBufferPos]) == MKTAG('A', 'N', 'I', 'M') || READ_BE_UINT24(&data[curBufferPos]) == MKTAG24('F', 'I', 'N')) innerLoopCond = true; if (bufSize < curBufferPos) { _animBqe[animIndex]._enabledFl = false; _animBqe[animIndex]._data = NULL; return; } ++curBufferPos; ++count; } while (!innerLoopCond); _animBqe[animIndex]._data = _vm->_globals->allocMemory(count + 50); _animBqe[animIndex]._enabledFl = true; memcpy(_animBqe[animIndex]._data, data + dataIdx + 5, 20); byte *dataP = _animBqe[animIndex]._data; int curDestDataIndx = 20; int curSrcDataIndx = dataIdx + 25; for (int i = 0; i <= 4999; i++) { memcpy(dataP + curDestDataIndx, data + curSrcDataIndx, 10); if (!READ_LE_UINT16(data + curSrcDataIndx + 4)) break; curDestDataIndx += 10; curSrcDataIndx += 10; } break; } } if (READ_BE_UINT24(&data[dataIdx]) == MKTAG24('F', 'I', 'N')) break; } } /** * Play sequence */ void AnimationManager::playSequence(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipEscFl, bool skipSeqFl, bool noColFl) { if (_vm->shouldQuit()) return; _vm->_events->_mouseFl = false; if (!noColFl) { _vm->_events->refreshScreenAndEvents(); _vm->_graphicsMan->backupScreen(); if (!_vm->_graphicsMan->_lineNbr) _vm->_graphicsMan->_scrollOffset = 0; } byte *screenP = _vm->_graphicsMan->_backBuffer; Common::File f; if (!f.open(file)) error("Error opening file - %s", file.c_str()); f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); if (skipSeqFl) { if (!_vm->getIsDemo()) { _vm->_graphicsMan->setColorPercentage(252, 100, 100, 100); _vm->_graphicsMan->setColorPercentage(253, 100, 100, 100); _vm->_graphicsMan->setColorPercentage(251, 100, 100, 100); _vm->_graphicsMan->setColorPercentage(254, 0, 0, 0); } _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); } else { _vm->_graphicsMan->copy16BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); } bool skipFl = false; if (noColFl) _vm->_graphicsMan->fadeInDefaultLength(screenP); _vm->_events->_rateCounter = 0; _vm->_events->_escKeyFl = false; _vm->_soundMan->loadAnimSound(); if (_vm->_globals->_eventMode == 1) { do { if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) { skipFl = true; break; } _vm->_events->_escKeyFl = false; _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (_vm->_events->_rateCounter < rate1); } _vm->_events->_rateCounter = 0; if (!skipFl) { int soundNumber = 0; for (;;) { ++soundNumber; _vm->_soundMan->playAnimSound(soundNumber); byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (_vm->_globals->_eventMode == 1) { do { if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) { skipFl = true; break; } _vm->_events->_escKeyFl = false; _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (_vm->_events->_rateCounter < rate2); } if (skipFl) break; _vm->_events->_rateCounter = 0; if (*screenP != kByteStop) _vm->_graphicsMan->copyVideoVbe16a(screenP); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); _vm->_soundMan->checkSoundEnd(); } } if (_vm->_globals->_eventMode == 1 && !skipFl) { do { if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) { skipFl = true; break; } _vm->_events->_escKeyFl = false; _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (_vm->_events->_rateCounter < rate3); } if (!skipFl) _vm->_events->_rateCounter = 0; _vm->_graphicsMan->_skipVideoLockFl = false; f.close(); if (!noColFl) { _vm->_graphicsMan->restoreScreen(); _vm->_events->_mouseFl = true; } } /** * Play Sequence type 2 */ void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) { byte *screenP; int frameNumber; Common::File f; for (;;) { if (_vm->shouldQuit()) return; _vm->_events->_mouseFl = false; screenP = _vm->_graphicsMan->_backBuffer; if (!f.open(file)) error("File not found - %s", file.c_str()); f.skip(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); if (skipSeqFl) { _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); } else { _vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette); _vm->_graphicsMan->copy16BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); } _vm->_events->_rateCounter = 0; _vm->_events->_escKeyFl = false; _vm->_soundMan->loadAnimSound(); if (_vm->_globals->_eventMode == 1) { do { _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1); } break; } if (!_vm->_events->_escKeyFl) { _vm->_events->_rateCounter = 0; frameNumber = 0; while (!_vm->shouldQuit()) { _vm->_soundMan->playAnimSound(frameNumber++); byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (_vm->_globals->_eventMode == 1) { do { _vm->_events->refreshEvents(); } while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2); } _vm->_events->_rateCounter = 0; if (*screenP != kByteStop) _vm->_graphicsMan->copyVideoVbe16a(screenP); _vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); _vm->_graphicsMan->updateScreen(); _vm->_soundMan->checkSoundEnd(); } } if (_vm->_globals->_eventMode == 1) { // Wait for third rate delay do { _vm->_events->refreshEvents(); _vm->_soundMan->checkSoundEnd(); } while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3); } _vm->_events->_rateCounter = 0; if (_vm->_graphicsMan->_fadingFl) { byte *ptra = _vm->_globals->allocMemory(307200); f.seek(6); f.read(_vm->_graphicsMan->_palette, 800); f.skip(4); size_t nbytes = f.readUint32LE(); f.skip(14); f.read(screenP, nbytes); memcpy(ptra, screenP, 307200); for (;;) { byte imageStr[17]; if (f.read(imageStr, 16) != 16) break; imageStr[16] = 0; if (strncmp((const char *)imageStr, "IMAGE=", 6)) break; f.read(screenP, READ_LE_UINT32(imageStr + 8)); if (*screenP != kByteStop) _vm->_graphicsMan->copyWinscanVbe(screenP, ptra); } _vm->_graphicsMan->fadeOutDefaultLength(ptra); ptra = _vm->_globals->freeMemory(ptra); } _vm->_graphicsMan->_fadingFl = false; f.close(); _vm->_events->_mouseFl = true; } void AnimationManager::initAnimBqe() { for (int idx = 0; idx < 35; ++idx) { _animBqe[idx]._data = NULL; _animBqe[idx]._enabledFl = false; } for (int idx = 0; idx < 8; ++idx) { Bank[idx]._data = NULL; Bank[idx]._loadedFl = false; Bank[idx]._filename = ""; Bank[idx]._fileHeader = 0; } } } // End of namespace Hopkins