aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/imd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/imd.cpp')
-rw-r--r--engines/gob/imd.cpp1249
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