diff options
Diffstat (limited to 'engines/gob/imd.cpp')
-rw-r--r-- | engines/gob/imd.cpp | 1249 |
1 files changed, 0 insertions, 1249 deletions
diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp deleted file mode 100644 index 395fb01f9b..0000000000 --- a/engines/gob/imd.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -/* 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. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/endian.h" - -#include "gob/gob.h" -#include "gob/imd.h" -#include "gob/global.h" -#include "gob/util.h" -#include "gob/dataio.h" -#include "gob/draw.h" -#include "gob/game.h" -#include "gob/inter.h" -#include "gob/palanim.h" -#include "gob/sound.h" -#include "gob/video.h" - -namespace Gob { - -ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) { - _curImd = 0; - _curFile[0] = 0; - - _curX = 0; - _curY = 0; - _left = 0; - _top = 0; - _right = 0; - _bottom = 0; - - _frameData = 0; - _vidBuffer = 0; - - _frontSurf = 21; - _backSurf = 21; - _frontMem = 0; - _frameDelay = 0; - - _noSound = true; - - _soundStartTime = 0; - _skipFrames = 0; - - _soundFreq = 0; - _soundSliceSize = 0; - _soundSlicesCount = 0; - - _soundSliceLength = 0; - _soundStage = 0; - - _audioStream = 0; -} - -ImdPlayer::~ImdPlayer() { - if (_curImd) { - delete[] _curImd->palette; - delete[] _curImd->framesPos; - delete[] _curImd->frameCoords; - delete[] _curImd->extraPalette; - } - delete[] _frameData; - delete[] _vidBuffer; - delete[] _frontMem; - delete _curImd; -} - -// flag bits: 0 = read and set palette -// 1 = read palette -ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc, int8 flags) { - Imd *imdPtr; - int16 handle; - char buf[18]; - uint32 framesPosPos = 0; - uint32 framesCordsPos = 0; - - strncpy0(buf, path, 17); - if (!strchr(buf, '.')) { - buf[13] = 0; - strcat(buf, ".IMD"); - } - - handle = _vm->_dataIO->openData(buf); - - if (handle < 0) { - warning("Can't open IMD \"%s\"", buf); - return 0; - } - - imdPtr = new Imd; - assert(imdPtr); - memset(imdPtr, 0, sizeof(Imd)); - - imdPtr->handle = _vm->_dataIO->readUint16(handle); - imdPtr->verMin = _vm->_dataIO->readUint16(handle); - imdPtr->framesCount = _vm->_dataIO->readUint16(handle); - imdPtr->x = _vm->_dataIO->readUint16(handle); - imdPtr->y = _vm->_dataIO->readUint16(handle); - imdPtr->width = _vm->_dataIO->readUint16(handle); - imdPtr->height = _vm->_dataIO->readUint16(handle); - imdPtr->field_E = _vm->_dataIO->readUint16(handle); - imdPtr->curFrame = _vm->_dataIO->readUint16(handle); - - if ((imdPtr->handle != 0) || ((imdPtr->verMin & 0xFF) < 2)) { - warning("%s: Version incorrect (%d,%X)", buf, imdPtr->handle, imdPtr->verMin); - _vm->_dataIO->closeData(handle); - delete imdPtr; - return 0; - } - - imdPtr->handle = handle; - imdPtr->surfDesc = surfDesc; - imdPtr->firstFramePos = imdPtr->curFrame; - imdPtr->curFrame = 0; - - if ((imdPtr->verMin & 0x800) && ((flags & 3) != 3)) - imdPtr->extraPalette = new Video::Color[256]; - - if (flags & 3) { - imdPtr->palette = new Video::Color[256]; - assert(imdPtr->palette); - _vm->_dataIO->readData(handle, (byte *) imdPtr->palette, 768); - } else - _vm->_dataIO->seekData(handle, 768, SEEK_CUR); - - if ((flags & 3) == 1) - _vm->_video->setPalette(imdPtr->palette); - - if ((imdPtr->verMin & 0xFF) >= 3) { - imdPtr->stdX = _vm->_dataIO->readUint16(handle); - if (imdPtr->stdX > 1) { - warning("%s: More than one standard coordinate quad found (%d)", - buf, imdPtr->stdX); - finishImd(imdPtr); - return 0; - } - if (imdPtr->stdX != 0) { - imdPtr->stdX = _vm->_dataIO->readUint16(handle); - imdPtr->stdY = _vm->_dataIO->readUint16(handle); - imdPtr->stdWidth = _vm->_dataIO->readUint16(handle); - imdPtr->stdHeight = _vm->_dataIO->readUint16(handle); - } else - imdPtr->stdX = -1; - } else - imdPtr->stdX = -1; - - if ((imdPtr->verMin & 0xFF) >= 4) { - framesPosPos = _vm->_dataIO->readUint32(handle); - if (framesPosPos != 0) { - imdPtr->framesPos = new int32[imdPtr->framesCount]; - assert(imdPtr->framesPos); - } - } - - if (imdPtr->verMin & 0x8000) - framesCordsPos = _vm->_dataIO->readUint32(handle); - - _noSound = true; - _soundStage = 0; - if (imdPtr->verMin & 0x4000) { - _soundFreq = _vm->_dataIO->readUint16(handle); - _soundSliceSize = _vm->_dataIO->readUint16(handle); - _soundSlicesCount = _vm->_dataIO->readUint16(handle); - - if (_soundFreq < 0) - _soundFreq = -_soundFreq; - - if (_soundSlicesCount < 0) - _soundSlicesCount = -_soundSlicesCount - 1; - - if (_soundSlicesCount > 40) { - warning("%s: More than 40 sound slices found (%d)", - buf, _soundSlicesCount); - finishImd(imdPtr); - return 0; - } - - _soundSliceLength = 1000 / (_soundFreq / _soundSliceSize); - - _soundStage = 1; - _noSound = false; - - _audioStream = Audio::makeAppendableAudioStream(_soundFreq, 0); - } - - if (imdPtr->verMin & 0x2000) { - imdPtr->frameDataSize = _vm->_dataIO->readUint16(handle); - if (imdPtr->frameDataSize == 0) { - imdPtr->frameDataSize = _vm->_dataIO->readUint32(handle); - imdPtr->vidBufferSize = _vm->_dataIO->readUint32(handle); - } else - imdPtr->vidBufferSize = _vm->_dataIO->readUint16(handle); - } else { - imdPtr->frameDataSize = imdPtr->width * imdPtr->height + 500; - if (!(imdPtr->field_E & 0x100) || (imdPtr->field_E & 0x1000)) - imdPtr->vidBufferSize = imdPtr->frameDataSize; - } - - if (imdPtr->framesPos) { - _vm->_dataIO->seekData(handle, framesPosPos, SEEK_SET); - for (int i = 0; i < imdPtr->framesCount; i++) - imdPtr->framesPos[i] = _vm->_dataIO->readUint32(handle); - } - - if (imdPtr->verMin & 0x8000) { - _vm->_dataIO->seekData(handle, framesCordsPos, SEEK_SET); - imdPtr->frameCoords = new ImdCoord[imdPtr->framesCount]; - assert(imdPtr->frameCoords); - for (int i = 0; i < imdPtr->framesCount; i++) { - imdPtr->frameCoords[i].left = _vm->_dataIO->readUint16(handle); - imdPtr->frameCoords[i].top = _vm->_dataIO->readUint16(handle); - imdPtr->frameCoords[i].right = _vm->_dataIO->readUint16(handle); - imdPtr->frameCoords[i].bottom = _vm->_dataIO->readUint16(handle); - } - } - - _vm->_dataIO->seekData(handle, imdPtr->firstFramePos, SEEK_SET); - return imdPtr; -} - -void ImdPlayer::finishImd(ImdPlayer::Imd *&imdPtr) { - if (!imdPtr) - return; - - if (_soundStage == 2) - _vm->_snd->stopSound(0); - - _vm->_dataIO->closeData(imdPtr->handle); - - delete[] imdPtr->frameCoords; - delete[] imdPtr->palette; - delete[] imdPtr->framesPos; - delete[] imdPtr->extraPalette; - - delete imdPtr; - - if (_audioStream) { - _audioStream->finish(); - _vm->_mixer->stopHandle(_audioHandle); - _audioStream = 0; - } -} - -int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, - int16 startFrame, int16 flags) { - const char *src; - byte *vidMem; - SurfaceDesc *surfDesc; - - if (!_curImd) - _curFile[0] = 0; - - src = strrchr(path, '\\'); - src = !src ? path : src + 1; - - if ((path[0] != 0) && scumm_stricmp(_curFile, src)) { - closeImd(); - - _curImd = loadImdFile(path, 0, 3); - if (!_curImd) - return 0; - - _curX = _curImd->x; - _curY = _curImd->y; - strncpy0(_curFile, src, 17); - - delete[] _frameData; - _frameData = new byte[_curImd->frameDataSize + 500]; - assert(_frameData); - memset(_frameData, 0, _curImd->frameDataSize + 500); - - delete[] _vidBuffer; - _vidBuffer = new byte[_curImd->vidBufferSize + 500]; - assert(_vidBuffer); - memset(_vidBuffer, 0, _curImd->vidBufferSize + 500); - - if (!(flags & 0x100)) { - - if (_vm->_global->_videoMode == 0x14) { - - _backSurf = (flags & 0x80) ? 20 : 21; - if (!(_curImd->field_E & 0x100) || (_curImd->field_E & 0x2000)) { - setXY(_curImd, 0, 0); - _curImd->surfDesc = - _vm->_video->initSurfDesc(0x13, - _curImd->width, _curImd->height, 0); - } else { - _curImd->surfDesc = _vm->_draw->_spritesArray[_frontSurf]; - if ((x != -1) || (y != -1)) { - _curX = x != -1 ? x : _curX; - _curY = y != -1 ? y : _curY; - setXY(_curImd, _curX, _curY); - } - } - - if (flags & 0x40) { - _curX = x != -1 ? x : _curX; - _curY = y != -1 ? y : _curY; - if (_curImd->surfDesc->_vidMode == 0x14) { - surfDesc = _vm->_video->initSurfDesc(0x13, - _curImd->width, _curImd->height, 0); - _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], - surfDesc, _curX, _curY, - _curX + _curImd->width - 1, _curY + _curImd->height - 1, - 0, 0, 0); - - vidMem = _curImd->surfDesc->getVidMem(); - for (int i = 0; i < _curImd->height; i++) - for (int j = 0; j < _curImd->width; j++, vidMem++) { - *(vidMem) = *(surfDesc->getVidMem() + - (j / 4) + (surfDesc->getWidth() / 4 * i)); - } - surfDesc = 0; - } - } - - } else { - if ((x != -1) || (y != -1)) { - _curX = (x != -1) ? x : _curX; - _curY = (y != -1) ? y : _curY; - setXY(_curImd, _curX, _curY); - } - _backSurf = (flags & 0x80) ? 20 : 21; - _curImd->surfDesc = _vm->_draw->_spritesArray[_backSurf]; - } - - } - } - - if (!_curImd) - return 0; - - if (startFrame == -1) { - closeImd(); - return 0; - } - - _curX = (x != -1) ? x : _curX; - _curY = (y != -1) ? y : _curY; - - WRITE_VAR(7, _curImd->framesCount); - - return 1; -} - -void ImdPlayer::closeImd(void) { - finishImd(_curImd); - - delete[] _frameData; - delete[] _vidBuffer; - _frameData = 0; - _vidBuffer = 0; - - _curImd = 0; -} - -void ImdPlayer::setXY(ImdPlayer::Imd *imdPtr, int16 x, int16 y) { - int i; - - if (imdPtr->stdX != -1) { - imdPtr->stdX = imdPtr->stdX - imdPtr->x + x; - imdPtr->stdY = imdPtr->stdY - imdPtr->y + y; - } - - if (imdPtr->frameCoords) { - for (i = 0; i < imdPtr->framesCount; i++) { - if (imdPtr->frameCoords[i].left != -1) { - imdPtr->frameCoords[i].left = - imdPtr->frameCoords[i].left - imdPtr->x + x; - imdPtr->frameCoords[i].top = - imdPtr->frameCoords[i].top - imdPtr->y + y; - imdPtr->frameCoords[i].right = - imdPtr->frameCoords[i].right - imdPtr->x + x; - imdPtr->frameCoords[i].bottom = - imdPtr->frameCoords[i].bottom - imdPtr->y + y; - } - } - } - - imdPtr->x = x; - imdPtr->y = y; -} - -void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y, - SurfaceDesc *dest) { - if (!dest) - dest = _vm->_draw->_frontSurface; - - if (frame == 0) - _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, - imdPtr->width - 1, imdPtr->height - 1, x, y, 0); - else if (imdPtr->frameCoords && (imdPtr->frameCoords[frame].left != -1)) - _vm->_video->drawSprite(imdPtr->surfDesc, dest, - imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, - imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom, - imdPtr->frameCoords[frame].left + x, - imdPtr->frameCoords[frame].top + y, 0); - else if (imdPtr->stdX != -1) - _vm->_video->drawSprite(imdPtr->surfDesc, dest, - imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1, - imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX, - y + imdPtr->stdY, 0); - else - _vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0, - imdPtr->width - 1, imdPtr->height - 1, x, y, 0); -} - -void ImdPlayer::renderFrame(Imd *imdPtr) { - int16 imdX, imdY; - int16 imdW, imdH; - int16 sW; - uint16 pixCount, pixWritten; - uint8 type; - byte *imdVidMem; - byte *imdVidMemBak; - byte *dataPtr = 0; - byte *srcPtr = 0; - - dataPtr = _frameData; - imdX = imdPtr->x; - imdY = imdPtr->y; - imdW = imdPtr->width; - imdH = imdPtr->height; - sW = imdPtr->surfDesc->getWidth(); - imdVidMem = imdPtr->surfDesc->getVidMem() + sW * imdY + imdX; - - type = *dataPtr++; - srcPtr = dataPtr; - - if (type & 0x10) { // Palette data - type ^= 0x10; - dataPtr += 49; - } - - srcPtr = dataPtr; - if (type & 0x80) { // Frame data is compressed - srcPtr = _vidBuffer; - type &= 0x7F; - if ((type == 2) && (imdW == sW)) { - frameUncompressor(imdVidMem, dataPtr); - return; - } else - frameUncompressor(srcPtr, dataPtr); - } - - if (type == 2) { // Whole block - for (int i = 0; i < imdH; i++) { - memcpy(imdVidMem, srcPtr, imdW); - srcPtr += imdW; - imdVidMem += sW; - } - } else if (type == 1) { // Sparse block - imdVidMemBak = imdVidMem; - for (int i = 0; i < imdH; i++) { - pixWritten = 0; - while (pixWritten < imdW) { - pixCount = *srcPtr++; - if (pixCount & 0x80) { // data - pixCount = MIN((pixCount & 0x7F) + 1, imdW - pixWritten); - memcpy(imdVidMem, srcPtr, pixCount); - - pixWritten += pixCount; - imdVidMem += pixCount; - srcPtr += pixCount; - } else { // "hole" - pixCount = (pixCount + 1) % 256; - pixWritten += pixCount; - imdVidMem += pixCount; - } - } - imdVidMemBak += sW; - imdVidMem = imdVidMemBak; - } - } else if (type == 0x42) { // Whole quarter-wide block - for (int i = 0; i < imdH; i++) { - imdVidMemBak = imdVidMem; - - for (int j = 0; j < imdW; j += 4, imdVidMem += 4, srcPtr++) - memset(imdVidMem, *srcPtr, 4); - - imdVidMemBak += sW; - imdVidMem = imdVidMemBak; - } - } else if ((type & 0xF) == 2) { // Whole half-high block - for (; imdH > 1; imdH -= 2, imdVidMem += sW + sW, srcPtr += imdW) { - memcpy(imdVidMem, srcPtr, imdW); - memcpy(imdVidMem + sW, srcPtr, imdW); - } - if (imdH == -1) - memcpy(imdVidMem, srcPtr, imdW); - } else { // Sparse half-high block - imdVidMemBak = imdVidMem; - for (int i = 0; i < imdH; i += 2) { - pixWritten = 0; - while (pixWritten < imdW) { - pixCount = *srcPtr++; - if (pixCount & 0x80) { // data - pixCount = MIN((pixCount & 0x7F) + 1, imdW - pixWritten); - memcpy(imdVidMem, srcPtr, pixCount); - memcpy(imdVidMem + sW, srcPtr, pixCount); - - pixWritten += pixCount; - imdVidMem += pixCount; - srcPtr += pixCount; - } else { // "hole" - pixCount = (pixCount + 1) % 256; - pixWritten += pixCount; - imdVidMem += pixCount; - } - } - imdVidMemBak += sW + sW; - imdVidMem = imdVidMemBak; - } - } -} - -void ImdPlayer::frameUncompressor(byte *dest, byte *src) { - int i; - byte buf[4370]; - uint16 chunkLength; - uint16 frameLength; - uint16 bufPos1; - uint16 bufPos2; - uint16 tmp; - uint8 chunkBitField; - uint8 chunkCount; - bool mode; - - frameLength = READ_LE_UINT16(src); - src += 4; - - if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) { - src += 4; - bufPos1 = 273; - mode = 1; // 123Ch (cmp al, 12h) - } else { - bufPos1 = 4078; - mode = 0; // 275h (jnz +2) - } - - memset(buf, 32, bufPos1); - chunkCount = 1; - chunkBitField = 0; - - while (frameLength > 0) { - chunkCount--; - if (chunkCount == 0) { - tmp = *src++; - chunkCount = 8; - chunkBitField = tmp; - } - if (chunkBitField % 2) { - chunkBitField >>= 1; - buf[bufPos1] = *src; - *dest++ = *src++; - bufPos1 = (bufPos1 + 1) % 4096; - frameLength--; - continue; - } - chunkBitField >>= 1; - - tmp = READ_LE_UINT16(src); - src += 2; - chunkLength = ((tmp & 0xF00) >> 8) + 3; - - if ((mode && ((chunkLength & 0xFF) == 0x12)) || - (!mode && (chunkLength == 0))) - chunkLength = *src++ + 0x12; - - bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00); - if (((tmp + chunkLength) >= 4096) || - ((chunkLength + bufPos1) >= 4096)) { - - for (i = 0; i < chunkLength; i++, dest++) { - *dest = buf[bufPos2]; - buf[bufPos1] = buf[bufPos2]; - bufPos1 = (bufPos1 + 1) % 4096; - bufPos2 = (bufPos2 + 1) % 4096; - } - - } else if (((tmp + chunkLength) < bufPos1) || - ((chunkLength + bufPos1) < bufPos2)) { - - memcpy(dest, buf + bufPos2, chunkLength); - memmove(buf + bufPos1, buf + bufPos2, chunkLength); - - dest += chunkLength; - bufPos1 += chunkLength; - bufPos2 += chunkLength; - - } else { - - for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) { - *dest = buf[bufPos2]; - buf[bufPos1] = buf[bufPos2]; - } - - } - frameLength -= chunkLength; - - } -} - -void ImdPlayer::play(const char *path, int16 x, int16 y, bool interruptible) { - int16 mouseX; - int16 mouseY; - int16 buttons; - - _vm->_util->setFrameRate(12); - if (!openImd(path, x, y, 0, 2)) - return; - - _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y, - x + _curImd->width - 1, y + _curImd->height - 1, 0); - - for (int i = 0; i < _curImd->framesCount; i++) { - play(i, 4, 0, 255, 0, _curImd->framesCount - 1); - - if (_vm->_quitRequested || (interruptible && - (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B))) - break; - } - - closeImd(); -} - -void ImdPlayer::play(const char *path, int16 x, int16 y, int16 startFrame, - int16 frames, bool fade, bool interruptible) { - int16 mouseX; - int16 mouseY; - int16 buttons = 0; - int endFrame; - - _vm->_util->setFrameRate(12); - if (!openImd(path, x, y, 0, 0)) - return; - - _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y, - x + _curImd->width - 1, y + _curImd->height - 1, 0); - - if (fade) - _vm->_palAnim->fade(0, -2, 0); - - endFrame = frames > 0 ? frames : _curImd->framesCount; - for (int i = startFrame; i < endFrame; i++) { - view(_curImd, i); - drawFrame(_curImd, i, x, y); - if (fade) { - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); - fade = false; - } - _vm->_video->waitRetrace(); - - if (_vm->_quitRequested || (interruptible && - (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B))) { - _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(_vm->_draw->_frontSurface); - memset((char *) _vm->_draw->_vgaPalette, 0, 768); - - WRITE_VAR(4, buttons); - WRITE_VAR(0, 0x11B); - WRITE_VAR(57, (uint32) -1); - break; - } - - _vm->_util->waitEndFrame(); - } - - if (frames < 0) { - endFrame = _curImd->framesCount + frames; - for (int i = _curImd->framesCount - 1; i >= endFrame; i--) { - seekFrame(_curImd, i, SEEK_SET, true); - drawFrame(_curImd, i, x, y); - _vm->_video->waitRetrace(); - - if (_vm->_quitRequested || (interruptible && - (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B))) { - _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(_vm->_draw->_frontSurface); - memset((char *) _vm->_draw->_vgaPalette, 0, 768); - - WRITE_VAR(4, buttons); - WRITE_VAR(0, 0x11B); - WRITE_VAR(57, (uint32) -1); - break; - } - - _vm->_util->waitEndFrame(); - } - } - - closeImd(); -} - -void ImdPlayer::play(int16 frame, uint16 palCmd, - int16 palStart, int16 palEnd, int16 palFrame, int16 lastFrame) { - uint32 viewRet = 0; - SurfaceDesc *surfDescBak; - bool modifiedPal = false; - - _vm->_draw->_showCursor = 0; - - if ((frame < 0) || (frame > lastFrame)) - return; - - palCmd &= 0x3F; - if ((frame == palFrame) || ((frame == lastFrame) && (palCmd == 8))) { - modifiedPal = true; - _vm->_draw->_applyPal = true; - - if (palCmd >= 4) - copyPalette(palStart, palEnd); - } - - if (modifiedPal && (palCmd == 8) && (_backSurf == 20)) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - - if (_curImd->surfDesc) { - if (_curImd->surfDesc->_vidMode == 0x14) { - - if ((_frontMem == _vm->_draw->_frontSurface->getVidMem()) && - (_frontSurf == 20)) { - _vm->_draw->_frontSurface->swap(_vm->_draw->_backSurface); - viewRet = view(_curImd, frame); - _vm->_draw->_frontSurface->swap(_vm->_draw->_backSurface); - } else - viewRet = view(_curImd, frame); - - if (_frontSurf == 21) - _vm->_draw->invalidateRect(_left, _top, _right, _bottom); - - } else { - if ((_curImd->field_E & 0x100) && - (_vm->_global->_videoMode == 0x14) && - (_frontSurf == 20) && - (checkFrameType(_curImd, frame) & 0x8000) && - (_backSurf == 21)) { - - surfDescBak = _curImd->surfDesc; - if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem()) - _curImd->surfDesc = _vm->_draw->_spritesArray[21]; - else - _curImd->surfDesc = _vm->_draw->_spritesArray[20]; - setXY(_curImd, _curX, _curY); - viewRet = view(_curImd, frame); - _curImd->surfDesc = surfDescBak; - setXY(_curImd, 0, 0); - - } else { - viewRet = view(_curImd, frame); - if (!(viewRet & 0x800)) - drawFrame(frame); - } - } - } else - viewRet = view(_curImd, frame); - - if (modifiedPal && (palCmd == 16)) { - if (_backSurf == 21) - _vm->_draw->forceBlit(); - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); - _vm->_draw->_noInvalidated = true; - } - - if (viewRet & 0x10) { - copyPalette(palStart, palEnd); - - if (_backSurf == 20) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - else - _vm->_draw->_applyPal = true; - } - - if (modifiedPal && (palCmd == 8) && (_backSurf == 21)) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - - if (!(viewRet & 0x800)) { - if (_vm->_draw->_cursorIndex == -1) { - if (_frontSurf == 20) - flipFrontMem(); - else - _vm->_draw->blitInvalidated(); - } else - _vm->_draw->animateCursor(-1); - } - - if (modifiedPal && ((palCmd == 2) || (palCmd == 4))) - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); - - // To allow quitting, etc. during IMDs - _vm->_util->processInput(); - if (_vm->_quitRequested) - return; - - if (_soundStage != 2) { - if (viewRet & 0x800) { - if (_frameDelay == 0) - _vm->_util->delay(30); - else { - _frameDelay -= 30; - if (_frameDelay < 0) - _frameDelay = 0; - } - } else - _vm->_util->waitEndFrame(); - } - - _vm->_inter->animPalette(); -} - -inline void ImdPlayer::drawFrame(int16 frame) { - if (_backSurf == 21) { - - if (_vm->_global->_videoMode == 0x14) { - if (_frontSurf == 21) { - _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]); - drawFrame(_curImd, frame, _curX, _curY); - _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]); - _vm->_draw->invalidateRect(_curX + _left, _curY + _top, - _curX + _right, _curY + _bottom); - } else { - if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem()) { - _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]); - drawFrame(_curImd, frame, _curX, _curY); - _vm->_draw->_frontSurface->swap(_vm->_draw->_spritesArray[21]); - } else - drawFrame(_curImd, frame, _curX, _curY); - } - } else - _vm->_draw->invalidateRect(_left, _top, _right, _bottom); - - } else if (_vm->_global->_videoMode == 0x14) - drawFrame(_curImd, frame, _curX, _curY); -} - -inline void ImdPlayer::copyPalette(int16 palStart, int16 palEnd) { - if ((palStart == -1) || (palEnd == -1)) - memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, - (char *) _curImd->palette, 768); - else - memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + - palStart * 3, ((char *) (_curImd->palette)) + palStart * 3, - (palEnd - palStart + 1) * 3); -} - -inline void ImdPlayer::flipFrontMem() { - if (_frontMem == _vm->_draw->_frontSurface->getVidMem()) - _frontMem = _vm->_draw->_backSurface->getVidMem(); - else - _frontMem = _vm->_draw->_frontSurface->getVidMem(); -} - -uint16 ImdPlayer::checkFrameType(Imd *imdPtr, int16 frame) { - uint16 retVal = 0; - uint32 posBak; - uint32 tmp; - uint16 cmd; - int16 frameBak; - - if (!imdPtr) - return 0x8000; - - posBak = _vm->_dataIO->getPos(imdPtr->handle); - frameBak = imdPtr->curFrame; - - if (imdPtr->curFrame != frame) { - retVal |= 0x2000; - seekFrame(imdPtr, frame, SEEK_SET); - } - - do { - if (frame != 0) { - if (imdPtr->stdX != -1) - retVal |= 0x1000; - if (imdPtr->frameCoords && (imdPtr->frameCoords[frame].left != -1)) - retVal |= 0x400; - } - - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - - if ((cmd & 0xFFF8) == 0xFFF0) { - if (cmd == 0xFFF0) { - _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR); - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - } - - if (cmd == 0xFFF1) { - retVal = 0x8000; - continue; - } else if (cmd == 0xFFF2) { // Skip (16 bit) - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR); - retVal = 0x8000; - continue; - } else if (cmd == 0xFFF3) { // Skip (32 bit) - tmp = _vm->_dataIO->readUint32(imdPtr->handle); - _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR); - retVal = 0x8000; - continue; - } - } - - // Jump to frame - if (cmd == 0xFFFD) { - frame = _vm->_dataIO->readUint16(imdPtr->handle); - if (imdPtr->framesPos) { - _vm->_dataIO->seekData(imdPtr->handle, - imdPtr->framesPos[frame], SEEK_SET); - retVal |= 0x200; - continue; - } - break; - } - - // Next sound slice data - if (cmd == 0xFF00) { - _vm->_dataIO->seekData(imdPtr->handle, - _soundSliceSize, SEEK_CUR); - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - // Initial sound data (all slices) - } else if (cmd == 0xFF01) { - _vm->_dataIO->seekData(imdPtr->handle, - _soundSliceSize * _soundSlicesCount, SEEK_CUR); - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - } - - // Frame video data - if (cmd != 0) { - _vm->_dataIO->readData(imdPtr->handle, _frameData, 5); - retVal |= _frameData[0]; - } else - retVal |= 0x800; - - break; - - } while (true); - - _vm->_dataIO->seekData(imdPtr->handle, posBak, SEEK_SET); - imdPtr->curFrame = frameBak; - return retVal; -} - -void ImdPlayer::seekFrame(Imd *imdPtr, int16 frame, int16 from, bool restart) { - uint32 framePos = 0; - - if (!imdPtr) - return; - - if (from == SEEK_CUR) - frame += imdPtr->curFrame; - else if (from == SEEK_END) - frame = imdPtr->framesCount - frame - 1; - - if (frame >= imdPtr->framesCount) - return; - - if (frame == 0) { - framePos = imdPtr->firstFramePos; - } else if (frame == 1) { - framePos = imdPtr->firstFramePos; - _vm->_dataIO->seekData(imdPtr->handle, framePos, SEEK_SET); - framePos += _vm->_dataIO->readUint16(imdPtr->handle) + 4; - } else if (imdPtr->framesPos) { - framePos = imdPtr->framesPos[frame]; - } else if (restart && (_soundStage == 0)) { - for (int i = 0; i <= frame; i++) - view(_curImd, i); - } else - error("%s: Frame %d is not directly accessible", _curFile, frame); - - _vm->_dataIO->seekData(imdPtr->handle, framePos, SEEK_SET); - imdPtr->curFrame = frame; -} - -uint32 ImdPlayer::view(Imd *imdPtr, int16 frame) { - uint32 retVal = 0; - uint32 cmd = 0; - int16 xBak, yBak, heightBak, widthBak; - bool hasNextCmd = false; - bool startSound = false; - - if (!imdPtr) - return 0x8000; - - if (frame != imdPtr->curFrame) { - retVal |= 0x2000; - seekFrame(imdPtr, frame, SEEK_SET); - } - - _left = xBak = imdPtr->x; - _top = yBak = imdPtr->y; - _bottom = heightBak= imdPtr->height; - _right = widthBak = imdPtr->width; - _right += _left - 1; - _bottom += _top - 1; - - if ((frame == 0) && (imdPtr->verMin & 0x800)) - _vm->_video->setPalette(imdPtr->palette); - - do { - if (frame != 0) { - if (imdPtr->stdX != -1) { - _left = imdPtr->x = imdPtr->stdX; - _top = imdPtr->y = imdPtr->stdY; - _right = imdPtr->width = imdPtr->stdWidth; - _bottom = imdPtr->height = imdPtr->stdHeight; - _right += _left - 1; - _bottom += _top - 1; - retVal |= 0x1000; - } - if (imdPtr->frameCoords && - (imdPtr->frameCoords[frame].left != -1)) { - _left = imdPtr->x = imdPtr->frameCoords[frame].left; - _top = imdPtr->y = imdPtr->frameCoords[frame].top; - _right = imdPtr->width = - imdPtr->frameCoords[frame].right - imdPtr->x + 1; - _bottom = imdPtr->height = - imdPtr->frameCoords[frame].bottom - imdPtr->y + 1; - _right += _left - 1; - _bottom += _top - 1; - retVal |= 0x400; - } - } - - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - - if ((cmd & 0xFFF8) == 0xFFF0) { - if (cmd == 0xFFF0) { - _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR); - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - } - - if (cmd == 0xFFF1) { - retVal = 0x8000; - continue; - } else if (cmd == 0xFFF2) { // Skip (16 bit) - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR); - retVal = 0x8000; - continue; - } else if (cmd == 0xFFF3) { // Skip (32 bit) - cmd = _vm->_dataIO->readUint32(imdPtr->handle); - _vm->_dataIO->seekData(imdPtr->handle, cmd, SEEK_CUR); - retVal = 0x8000; - continue; - } - } - - if (_soundStage != 0) { - byte *soundBuf; - - if (!hasNextCmd) - waitEndSoundSlice(); - - // Next sound slice data - if (cmd == 0xFF00) { - - if (!hasNextCmd && !_noSound) { - soundBuf = new byte[_soundSliceSize]; - assert(soundBuf); - - _vm->_dataIO->readData(imdPtr->handle, soundBuf, - _soundSliceSize); - _vm->_snd->convToSigned(soundBuf, _soundSliceSize); - _audioStream->queueBuffer(soundBuf, _soundSliceSize); - } else - _vm->_dataIO->seekData(imdPtr->handle, - _soundSliceSize, SEEK_CUR); - - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - - // Initial sound data (all slices) - } else if (cmd == 0xFF01) { - int dataLength = _soundSliceSize * _soundSlicesCount; - - if (!hasNextCmd && !_noSound) { - soundBuf = new byte[dataLength]; - assert(soundBuf); - - _vm->_dataIO->readData(imdPtr->handle, soundBuf, dataLength); - _vm->_snd->convToSigned(soundBuf, dataLength); - - _soundStage = 1; - startSound = true; - _audioStream->queueBuffer(soundBuf, dataLength); - } else - _vm->_dataIO->seekData(imdPtr->handle, dataLength, SEEK_CUR); - - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - - // Empty sound slice - } else if (!hasNextCmd && (!_noSound)) { - soundBuf = new byte[_soundSliceSize]; - assert(soundBuf); - - memset(soundBuf, 0, _soundSliceSize); - _audioStream->queueBuffer(soundBuf, _soundSliceSize); - } - } - - // Set palette - if (cmd == 0xFFF4) { - _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR); - retVal |= 0x10; - if (imdPtr->extraPalette) { - _vm->_dataIO->readData(imdPtr->handle, - (byte *) imdPtr->extraPalette, 768); - _vm->_video->setPalette(imdPtr->extraPalette); - } else if (imdPtr->palette) - _vm->_dataIO->readData(imdPtr->handle, - (byte *) imdPtr->palette, 768); - else - _vm->_dataIO->readData(imdPtr->handle, _frameData, 768); - - cmd = _vm->_dataIO->readUint16(imdPtr->handle); - } - - hasNextCmd = false; - - // Jump to frame - if (cmd == 0xFFFD) { - - frame = _vm->_dataIO->readUint16(imdPtr->handle); - if (imdPtr->framesPos) { - imdPtr->curFrame = frame; - _vm->_dataIO->seekData(imdPtr->handle, - imdPtr->framesPos[frame], SEEK_SET); - - hasNextCmd = true; - retVal |= 0x200; - } - - } else if (cmd == 0xFFFC) { - - retVal |= 1; - cmd = _vm->_dataIO->readUint32(imdPtr->handle); - _vm->_dataIO->readData(imdPtr->handle, _frameData, cmd + 2); - - if (imdPtr->surfDesc) { - int16 left = imdPtr->x; - int16 top = imdPtr->y; - int16 right = imdPtr->width + left; - int16 bottom = imdPtr->height + top; - - if (imdPtr->surfDesc->getWidth() < right) { - left = 0; - right = imdPtr->width; - } - if (imdPtr->surfDesc->getWidth() < right) - right = imdPtr->surfDesc->getWidth(); - if (imdPtr->surfDesc->getHeight() < bottom) { - top = 0; - bottom = imdPtr->height; - } - if (imdPtr->surfDesc->getHeight() < bottom) - bottom = imdPtr->surfDesc->getHeight(); - - imdPtr->x = left; - imdPtr->y = top; - imdPtr->height = bottom - top; - imdPtr->width = right - left; - - renderFrame(imdPtr); - } - - retVal |= _frameData[0]; - - // Frame video data - } else if (cmd != 0) { - - _vm->_dataIO->readData(imdPtr->handle, _frameData, cmd + 2); - if (imdPtr->surfDesc) - renderFrame(imdPtr); - - retVal |= _frameData[0]; - - } else - retVal |= 0x800; - - } while (hasNextCmd); - - if (startSound) { - _vm->_snd->stopSound(0); - _vm->_mixer->playInputStream(Audio::Mixer::kSFXSoundType, &_audioHandle, _audioStream); - _soundStartTime = _vm->_util->getTimeKey(); - _skipFrames = 0; - _soundStage = 2; - } - - imdPtr->x = xBak; - imdPtr->y = yBak; - imdPtr->width = widthBak; - imdPtr->height = heightBak; - - imdPtr->curFrame++; - if ((imdPtr->curFrame == imdPtr->framesCount) && (_soundStage == 2)) { - waitEndSoundSlice(); - _audioStream->finish(); - _vm->_mixer->stopHandle(_audioHandle); - _audioStream = 0; - } - - return retVal; -} - -inline void ImdPlayer::waitEndSoundSlice() { - if (_soundStage != 2) - return; - - if (_skipFrames == 0) { - - _vm->_video->retrace(); - - int32 waitTime = (_curImd->curFrame * _soundSliceLength) - - (_vm->_util->getTimeKey() - _soundStartTime); - - if (waitTime < 0) { - _skipFrames = -waitTime / _soundSliceLength; - warning("IMD A/V sync broken, skipping %d frame(s)", _skipFrames + 1); - } else if (waitTime > 0) - _vm->_util->delay(waitTime); - - } else - _skipFrames--; -} - -} // End of namespace Gob |