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.cpp1342
1 files changed, 797 insertions, 545 deletions
diff --git a/engines/gob/imd.cpp b/engines/gob/imd.cpp
index 48789ea39a..7f2ad3d211 100644
--- a/engines/gob/imd.cpp
+++ b/engines/gob/imd.cpp
@@ -44,9 +44,11 @@ ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) {
_curX = 0;
_curY = 0;
+ _left = 0;
+ _top = 0;
+ _right = 0;
+ _bottom = 0;
- _frameDataSize = 0;
- _vidBufferSize = 0;
_frameData = 0;
_vidBuffer = 0;
@@ -54,35 +56,42 @@ ImdPlayer::ImdPlayer(GobEngine *vm) : _vm(vm) {
_backSurf = 21;
_frontMem = 0;
_frameDelay = 0;
+
+ _noSound = true;
+ _soundBuffer = 0;
+
+ _soundFreq = 0;
+ _soundSliceSize = 0;
+ _soundSlicesCount = 0;
+
+ _soundSliceLength = 0;
+ _curSoundSlice = 0;
+ _soundStage = 0;
}
ImdPlayer::~ImdPlayer() {
if (_curImd) {
- _curImd->surfDesc = 0;
delete[] _curImd->palette;
delete[] _curImd->framesPos;
delete[] _curImd->frameCoords;
+ delete[] _curImd->extraPalette;
}
delete[] _frameData;
delete[] _vidBuffer;
delete[] _frontMem;
+ delete[] _soundBuffer;
delete _curImd;
}
-// flagsBit: 0 = read and set palette
-// 1 = read palette
+// flag bits: 0 = read and set palette
+// 1 = read palette
ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc, int8 flags) {
- int i;
Imd *imdPtr;
int16 handle;
- bool setAllPalBak;
char buf[18];
- Video::Color *palBak;
+ uint32 framesPosPos = 0;
+ uint32 framesCordsPos = 0;
- int32 byte_31449 = 0;
- int32 byte_3144D = 0;
-
- buf[0] = 0;
strcpy(buf, path);
strcat(buf, ".IMD");
@@ -94,226 +103,204 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc,
}
imdPtr = new Imd;
+ assert(imdPtr);
memset(imdPtr, 0, sizeof(Imd));
- _vm->_dataIO->readData(handle, buf, 18);
-
- // "fileHandle" holds the major version while loading
- imdPtr->fileHandle = READ_LE_UINT16(buf);
- imdPtr->verMin = READ_LE_UINT16(buf + 2);
- imdPtr->framesCount = READ_LE_UINT16(buf + 4);
- imdPtr->x = READ_LE_UINT16(buf + 6);
- imdPtr->y = READ_LE_UINT16(buf + 8);
- imdPtr->width = READ_LE_UINT16(buf + 10);
- imdPtr->height = READ_LE_UINT16(buf + 12);
- imdPtr->field_E = READ_LE_UINT16(buf + 14);
- imdPtr->curFrame = READ_LE_UINT16(buf + 16);
-
- if (imdPtr->fileHandle != 0)
- imdPtr->verMin = 0;
-
- if ((imdPtr->verMin & 0xFF) < 2) {
- warning("IMD version incorrect (%d,%d)", imdPtr->fileHandle, imdPtr->verMin);
+ 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;
-/*
- imdPtr->field_3A = 0;
if ((imdPtr->verMin & 0x800) && ((flags & 3) != 3))
- imdPtr->field_3A = new Video::Color[256];
-*/
+ imdPtr->extraPalette = new Video::Color[256];
if (flags & 3) {
imdPtr->palette = new Video::Color[256];
+ assert(imdPtr->palette);
_vm->_dataIO->readData(handle, (char *) imdPtr->palette, 768);
- } else {
- imdPtr->palette = 0;
- _vm->_dataIO->seekData(handle, 768, 1);
- }
-
- if ((flags & 3) == 1) {
- palBak = _vm->_global->_pPaletteDesc->vgaPal;
- setAllPalBak = _vm->_global->_setAllPalette;
-
- _vm->_global->_pPaletteDesc->vgaPal = imdPtr->palette;
- _vm->_global->_setAllPalette = true;
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ } else
+ _vm->_dataIO->seekData(handle, 768, SEEK_CUR);
- _vm->_global->_setAllPalette = setAllPalBak;
- _vm->_global->_pPaletteDesc->vgaPal = palBak;
- }
+ if ((flags & 3) == 1)
+ _vm->_video->setPalette(imdPtr->palette);
if ((imdPtr->verMin & 0xFF) >= 3) {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->stdX = READ_LE_UINT16(buf);
+ imdPtr->stdX = _vm->_dataIO->readUint16(handle);
if (imdPtr->stdX > 1) {
- warning("IMD ListI incorrect (%d)", imdPtr->stdX);
- _vm->_dataIO->closeData(handle);
- delete imdPtr;
+ warning("%s: More than one standard coordinate quad found (%d)",
+ buf, imdPtr->stdX);
+ finishImd(imdPtr);
return 0;
}
if (imdPtr->stdX != 0) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->stdX = READ_LE_UINT16(buf);
- imdPtr->stdY = READ_LE_UINT16(buf + 2);
- imdPtr->stdWidth = READ_LE_UINT16(buf + 4);
- imdPtr->stdHeight = READ_LE_UINT16(buf + 6);
+ 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;
- imdPtr->framesPos = 0;
if ((imdPtr->verMin & 0xFF) >= 4) {
- _vm->_dataIO->readData(handle, buf, 4);
- byte_31449 = READ_LE_UINT32(buf);
- if (byte_31449 != 0)
+ framesPosPos = _vm->_dataIO->readUint32(handle);
+ if (framesPosPos != 0) {
imdPtr->framesPos = new int32[imdPtr->framesCount];
+ assert(imdPtr->framesPos);
+ }
}
- if (imdPtr->verMin & 0x8000) {
- _vm->_dataIO->readData(handle, buf, 4);
- byte_3144D = READ_LE_UINT32(buf);
- }
+ if (imdPtr->verMin & 0x8000)
+ framesCordsPos = _vm->_dataIO->readUint32(handle);
- if (imdPtr->verMin & 0x4000) { // loc_29C4F
- int16 word_3145B[3];
+ _noSound = true;
+ if (imdPtr->verMin & 0x4000) {
+ _soundFreq = _vm->_dataIO->readUint16(handle);
+ _soundSliceSize = _vm->_dataIO->readUint16(handle);
+ _soundSlicesCount = _vm->_dataIO->readUint16(handle);
- flags &= 0x7F;
- _vm->_dataIO->readData(handle, buf, 6);
- word_3145B[0] = READ_LE_UINT16(buf);
- word_3145B[1] = READ_LE_UINT16(buf + 2);
- word_3145B[2] = READ_LE_UINT16(buf + 4);
+ if (_soundFreq < 0)
+ _soundFreq = -_soundFreq;
- if (word_3145B[0] < 0)
- word_3145B[0] = -word_3145B[0];
- if (word_3145B[2] < 0)
- word_3145B[2] = -word_3145B[2];
+ if (_soundSlicesCount < 0)
+ _soundSlicesCount = -_soundSlicesCount - 1;
- warning("Imd Stub! Sound stuff!");
- return 0;
- } // loc_29E43
+ if (_soundSlicesCount >= 40) {
+ warning("%s: More than 40 sound slices found (%d)",
+ buf, _soundSlicesCount + 1);
+ finishImd(imdPtr);
+ return 0;
+ }
+
+ _soundSliceLength = 1000 / (_soundFreq / _soundSliceSize);
+
+ delete[] _soundBuffer;
+ _soundBuffer = new byte[_soundSliceSize * _soundSlicesCount];
+ assert(_soundBuffer);
+ memset(_soundBuffer, 0, _soundSliceSize * _soundSlicesCount);
+
+ _vm->_snd->stopSound(0);
+ _soundDesc.set(SOUND_SND, SOUND_TOT, _soundBuffer,
+ _soundSliceSize * _soundSlicesCount);
+
+ _curSoundSlice = 0;
+ _soundStage = 1;
+ _noSound = false;
+ }
if (imdPtr->verMin & 0x2000) {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->frameDataSize = READ_LE_UINT16(buf);
+ imdPtr->frameDataSize = _vm->_dataIO->readUint16(handle);
if (imdPtr->frameDataSize == 0) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->frameDataSize = READ_LE_UINT32(buf);
- imdPtr->vidBufferSize = READ_LE_UINT32(buf + 4);
- } else {
- _vm->_dataIO->readData(handle, buf, 2);
- imdPtr->vidBufferSize = READ_LE_UINT16(buf);
- }
+ 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;
- imdPtr->vidBufferSize = 0;
if (!(imdPtr->field_E & 0x100) || (imdPtr->field_E & 0x1000))
- imdPtr->vidBufferSize = imdPtr->width * imdPtr->height + 500;
+ imdPtr->vidBufferSize = imdPtr->frameDataSize;
}
- warning("-> %d, %d", imdPtr->frameDataSize, imdPtr->vidBufferSize);
- if (imdPtr->framesPos != 0) {
- _vm->_dataIO->seekData(handle, byte_31449, 0);
- for (i = 0; i < imdPtr->framesCount; i++) {
- _vm->_dataIO->readData(handle, buf, 4);
- imdPtr->framesPos[i] = READ_LE_UINT32(buf);
- }
+ 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, byte_3144D, 0);
+ _vm->_dataIO->seekData(handle, framesCordsPos, SEEK_SET);
imdPtr->frameCoords = new ImdCoord[imdPtr->framesCount];
- for (i = 0; i < imdPtr->framesCount; i++) {
- _vm->_dataIO->readData(handle, buf, 8);
- imdPtr->frameCoords[i].left = READ_LE_UINT16(buf);
- imdPtr->frameCoords[i].top = READ_LE_UINT16(buf + 2);
- imdPtr->frameCoords[i].right = READ_LE_UINT16(buf + 4);
- imdPtr->frameCoords[i].bottom = READ_LE_UINT16(buf + 6);
+ 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);
}
- } else
- imdPtr->frameCoords = 0;
-
- _vm->_dataIO->seekData(handle, imdPtr->firstFramePos, 0);
- imdPtr->curFrame = 0;
- imdPtr->fileHandle = handle;
- imdPtr->filePos = imdPtr->firstFramePos;
- _frameDataSize = imdPtr->frameDataSize;
- _vidBufferSize = imdPtr->vidBufferSize;
- if (flags & 0x80) {
- imdPtr->verMin |= 0x1000;
- warning("Imd Stub! loadImdFile(), flags & 0x80");
}
+ _vm->_dataIO->seekData(handle, imdPtr->firstFramePos, SEEK_SET);
return imdPtr;
}
-void ImdPlayer::finishImd(ImdPlayer::Imd *imdPtr) {
- if (imdPtr == 0)
+void ImdPlayer::finishImd(ImdPlayer::Imd *&imdPtr) {
+ if (!imdPtr)
return;
-/*
- if (dword_31345 != 0) {
- _vm->_sound->stopSound(0);
- dword_31345 = 0;
- delete off_31461;
- byte_31344 = 0;
- }
-*/
+ _soundDesc.free();
+ if (_soundStage == 2)
+ _vm->_snd->stopSound(0);
- _vm->_dataIO->closeData(imdPtr->fileHandle);
+ _vm->_dataIO->closeData(imdPtr->handle);
- if (imdPtr->frameCoords != 0)
- delete[] imdPtr->frameCoords;
- if (imdPtr->palette != 0)
- delete[] imdPtr->palette;
- if (imdPtr->framesPos != 0)
- delete[] imdPtr->framesPos;
+ delete[] imdPtr->frameCoords;
+ delete[] imdPtr->palette;
+ delete[] imdPtr->framesPos;
+ delete[] imdPtr->extraPalette;
delete imdPtr;
- imdPtr = 0;
}
-int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) {
- int i;
- int j;
+int8 ImdPlayer::openImd(const char *path, int16 x, int16 y,
+ int16 startFrame, int16 flags) {
const char *src;
byte *vidMem;
SurfaceDesc *surfDesc;
- if (path[0] != 0) {
+ 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)
- _curFile[0] = 0;
+ return 0;
- src = strrchr(path, '\\');
- src = src == 0 ? path : src+1;
+ _curX = _curImd->x;
+ _curY = _curImd->y;
+ strcpy(_curFile, src);
- if (strcmp(_curFile, src) != 0) {
- closeImd();
+ delete[] _frameData;
+ _frameData = new byte[_curImd->frameDataSize + 500];
+ assert(_frameData);
+ memset(_frameData, 0, _curImd->frameDataSize + 500);
- _curImd = loadImdFile(path, 0, 2);
- if (!_curImd)
- return 0;
+ delete[] _vidBuffer;
+ _vidBuffer = new byte[_curImd->vidBufferSize + 500];
+ assert(_vidBuffer);
+ memset(_vidBuffer, 0, _curImd->vidBufferSize + 500);
- _curX = _curImd->x;
- _curY = _curImd->y;
- strcpy(_curFile, src);
- _frameData = new byte[_frameDataSize + 500];
- _vidBuffer = new byte[_vidBufferSize + 500];
- memset(_frameData, 0, _frameDataSize + 500);
- memset(_vidBuffer, 0, _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);
+ _vm->_video->initSurfDesc(0x13,
+ _curImd->width, _curImd->height, 0);
} else {
_curImd->surfDesc = _vm->_draw->_spritesArray[_frontSurf];
if ((x != -1) || (y != -1)) {
@@ -322,44 +309,51 @@ int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16
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);
+ 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 (i = 0; i < _curImd->height; i++)
- for (j = 0; j < _curImd->width; j++, vidMem++) {
+ 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;
+ _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 (repeat == -1) {
+ if (startFrame == -1) {
closeImd();
return 0;
}
- _curX = x != -1 ? x : _curX;
- _curY = y != -1 ? y : _curY;
+ _curX = (x != -1) ? x : _curX;
+ _curY = (y != -1) ? y : _curY;
WRITE_VAR(7, _curImd->framesCount);
@@ -367,16 +361,14 @@ int8 ImdPlayer::openImd(const char *path, int16 x, int16 y, int16 repeat, int16
}
void ImdPlayer::closeImd(void) {
- if (_curImd == 0)
- return;
-
- _curImd->surfDesc = 0;
finishImd(_curImd);
delete[] _frameData;
delete[] _vidBuffer;
+ delete[] _soundBuffer;
_frameData = 0;
_vidBuffer = 0;
+ _soundBuffer = 0;
_curImd = 0;
}
@@ -389,317 +381,23 @@ void ImdPlayer::setXY(ImdPlayer::Imd *imdPtr, int16 x, int16 y) {
imdPtr->stdY = imdPtr->stdY - imdPtr->y + y;
}
- if (imdPtr->frameCoords != 0) {
+ if (imdPtr->frameCoords) {
for (i = 0; i < imdPtr->framesCount; i++) {
- 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::play(int16 frame, uint16 palCmd, int16 palStart, int16 palEnd, int16 palFrame, int16 lastFrame) {
- int16 viewRet = 0;
- bool modifiedPal = false;
- SurfaceDesc *surfDescBak;
-
- _vm->_draw->_showCursor = 0;
-
- int8 byte_31344 = 0;
-
- if ((frame < 0) || (frame > lastFrame))
- return;
-
- if ((frame == palFrame) || ((frame == lastFrame) && (palCmd == 8))) { // loc_1C3F0
- modifiedPal = true;
- _vm->_draw->_applyPal = false;
- if (palCmd >= 4) {
- if (palStart != -1)
- memcpy( ((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3,
- ((char *) (_curImd->palette)) + palStart * 3, (palEnd - palStart + 1) * 3);
- else
- memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, (char *) _curImd->palette, 768);
- }
- }
-
- if (modifiedPal && (palCmd == 8) && (_backSurf == 20))
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- if (_curImd->surfDesc->_vidMode == 0x14) {
- if ((_frontSurf == 20) && (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())) {
- _vm->_draw->_spritesArray[20]->swap(_vm->_draw->_spritesArray[21]);
- viewRet = view(_curImd, frame);
- _vm->_draw->_spritesArray[20]->swap(_vm->_draw->_spritesArray[21]);
- } else
- viewRet = view(_curImd, frame);
- if (_frontSurf == 21) {
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY,
- _curX + _curImd->width - 1, _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- }
- } else {
- if ((_curImd->field_E & 0x100) && (_vm->_global->_videoMode == 0x14) &&
- (_frontSurf == 20) && (sub_2C825(_curImd) & 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)) {
- 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]);
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY, _curX + _curImd->width - 1,
- _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- } else {
- if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem()) { // loc_1C68D
- _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 {
- if ((_curImd->frameCoords == 0) || (_curImd->frameCoords[frame].left == -1))
- _vm->_draw->invalidateRect(_curX, _curY, _curX + _curImd->width - 1,
- _curY + _curImd->height - 1);
- else
- _vm->_draw->invalidateRect(_curImd->frameCoords[frame].left,
- _curImd->frameCoords[frame].top, _curImd->frameCoords[frame].right,
- _curImd->frameCoords[frame].bottom);
- }
- } else
- if (_vm->_global->_videoMode == 0x14)
- drawFrame(_curImd, frame, _curX, _curY);
- }
- }
- }
-
- if (modifiedPal && (palCmd == 16)) {
- if ((_vm->_draw->_spritesArray[20] != _vm->_draw->_spritesArray[21]) && (_backSurf == 21))
- _vm->_video->drawSprite(_vm->_draw->_spritesArray[21],
- _vm->_draw->_spritesArray[20], 0, 0,
- _vm->_draw->_spritesArray[21]->getWidth() - 1,
- _vm->_draw->_spritesArray[21]->getHeight() - 1, 0, 0, 0);
- _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
- _vm->_draw->_noInvalidated = true;
- }
- if (modifiedPal && (palCmd == 8) && (_backSurf == 21))
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- if (!(viewRet & 0x800)) {
- if (_vm->_draw->_cursorIndex == -1) {
- if (_frontSurf == 20) {
- if (_frontMem == _vm->_draw->_spritesArray[20]->getVidMem())
- _frontMem = _vm->_draw->_spritesArray[21]->getVidMem();
- else
- _frontMem = _vm->_draw->_spritesArray[20]->getVidMem();
- warning("GOB2 Stub! sub_1BC3A(_frontMem);");
- } 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 (byte_31344 != 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();
-}
-
-int16 ImdPlayer::view(ImdPlayer::Imd *imdPtr, int16 frame) {
- int16 x;
- int16 y;
- int16 width;
- int16 height;
- int16 retVal;
- uint32 tmp;
- char buf[4];
-
- int8 var_4;
- int32 var_12 = 0;
-
- // .---
- int16 word_31451 = 0;
- int8 byte_31344 = 0;
- int8 byte_2DA60 = 0;
- int16 word_2DA61 = -1;
- // '---
-
- word_31451 = 0;
-
- if (imdPtr == 0)
- return (int16)0x8000;
-
- retVal = 0;
- var_4 = 0;
-
- if (frame != imdPtr->curFrame) {
- retVal |= 0x2000;
- if (frame == 0)
- imdPtr->filePos = imdPtr->firstFramePos;
- else if (frame == 1) {
- imdPtr->filePos = imdPtr->firstFramePos;
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += tmp + 4;
- } else if (imdPtr->framesPos != 0)
- imdPtr->filePos = imdPtr->framesPos[frame];
- else
- error("Image %d inaccessible in IMD", frame);
- imdPtr->curFrame = frame;
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- }
-
- x = imdPtr->x;
- y = imdPtr->y;
- width = imdPtr->width;
- height = imdPtr->height;
-
- do {
- if (frame != 0) {
- if (imdPtr->stdX != -1) {
- imdPtr->x = imdPtr->stdX;
- imdPtr->y = imdPtr->stdY;
- imdPtr->width = imdPtr->stdWidth;
- imdPtr->height = imdPtr->stdHeight;
- retVal |= 0x1000;
- }
- if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1)) {
- var_4 |= 0x400;
- imdPtr->x = imdPtr->frameCoords[frame].left;
- imdPtr->y = imdPtr->frameCoords[frame].top;
- imdPtr->width = imdPtr->frameCoords[frame].right - imdPtr->x + 1;
- imdPtr->height = imdPtr->frameCoords[frame].bottom - imdPtr->y + 1;
+ 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;
}
}
-
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
-
- imdPtr->filePos += 2;
-
- if ((tmp & 0xFFF8) == 0xFFF0) {
- if (tmp == 0xFFF0) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- if (var_4 == 0)
- word_31451 = tmp;
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += 4;
- } else if (tmp == 0xFFF1) {
- retVal = (int16)0x8000;
- continue;
- } else if (tmp == 0xFFF2) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- tmp = READ_LE_UINT16(buf);
- imdPtr->filePos += 2;
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp, 1);
- imdPtr->filePos += tmp;
- retVal = (int16)0x8000;
- continue;
- } else if (tmp == 0xFFF3) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 4);
- tmp = READ_LE_UINT32(buf);
- imdPtr->filePos += 4;
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp, 1);
- imdPtr->filePos += tmp;
- retVal = (int16)0x8000;
- continue;
- }
- }
- if (byte_31344 != 0) {
- if ((var_4 == 0) && (_vm->_global->_soundFlags & 0x14) && (byte_31344 == 2)) { // loc_2A503
- var_12 = _vm->_util->getTimeKey();
- warning("GOB2 Stub! view, IMD sound stuff");
- }
- }
- var_4 = 0;
- if (tmp == 0xFFFD) {
- _vm->_dataIO->readData(imdPtr->fileHandle, buf, 2);
- frame = READ_LE_UINT16(buf);
- if ((imdPtr->framesPos != 0) && (byte_2DA60 == 0)) {
- word_2DA61 = frame;
- imdPtr->filePos = imdPtr->framesPos[frame];
- _vm->_dataIO->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
- var_4 = 1;
- retVal |= 0x200;
- imdPtr->curFrame = frame;
- } else
- imdPtr->filePos += 2;
- continue;
- }
- if (tmp != 0) {
- imdPtr->filePos += tmp + 2;
- if (byte_2DA60 != 0) {
- _vm->_dataIO->seekData(imdPtr->fileHandle, tmp + 2, 1);
- } else {
- _vm->_dataIO->readData(imdPtr->fileHandle, (char *) _frameData, tmp + 2);
- retVal |= *_frameData;
- if (imdPtr->surfDesc == 0)
- continue;
- if (imdPtr->surfDesc->_vidMode != 0x14)
- renderframe(imdPtr);
- else
- warning("GOB2 Stub! viedImd, sub_2C69A(imdPtr);");
- }
- } else
- retVal |= 0x800;
- } while (var_4 != 0);
-
- if (byte_2DA60 != 0) {
- byte_2DA60 = 0;
- retVal |= 0x100;
}
imdPtr->x = x;
imdPtr->y = y;
- imdPtr->width = width;
- imdPtr->height = height;
- imdPtr->curFrame++;
-
- return retVal;
}
void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
@@ -710,7 +408,7 @@ void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
if (frame == 0)
_vm->_video->drawSprite(imdPtr->surfDesc, dest, 0, 0,
imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
- else if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1))
+ 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,
@@ -725,12 +423,9 @@ void ImdPlayer::drawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y,
imdPtr->width - 1, imdPtr->height - 1, x, y, 0);
}
-void ImdPlayer::renderframe(Imd *imdPtr) {
- int i;
- int16 imdX;
- int16 imdY;
- int16 imdW;
- int16 imdH;
+void ImdPlayer::renderFrame(Imd *imdPtr) {
+ int16 imdX, imdY;
+ int16 imdW, imdH;
int16 sW;
uint16 pixCount, pixWritten;
uint8 type;
@@ -738,7 +433,6 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
byte *imdVidMemBak;
byte *dataPtr = 0;
byte *srcPtr = 0;
- byte *srcPtrBak = 0;
dataPtr = (byte *) _frameData;
imdX = imdPtr->x;
@@ -751,14 +445,13 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
type = *dataPtr++;
srcPtr = dataPtr;
- if (type & 0x10) {
+ if (type & 0x10) { // Palette data
type ^= 0x10;
- dataPtr++; // => 0x3C8 |_ palette
- dataPtr += 48; // => 0x3C9 | stuff
+ dataPtr += 49;
}
srcPtr = dataPtr;
- if (type & 0x80) {
+ if (type & 0x80) { // Frame data is compressed
srcPtr = (byte *) _vidBuffer;
type &= 0x7F;
if ((type == 2) && (imdW == sW)) {
@@ -768,27 +461,26 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
frameUncompressor(srcPtr, dataPtr);
}
- if (type == 2) {
- for (i = 0; i < imdH; i++) {
+ if (type == 2) { // Whole block
+ for (int i = 0; i < imdH; i++) {
memcpy(imdVidMem, srcPtr, imdW);
srcPtr += imdW;
imdVidMem += sW;
}
- } else if (type == 1) {
+ } else if (type == 1) { // Sparse block
imdVidMemBak = imdVidMem;
- for (i = 0; i < imdH; i++) {
+ for (int i = 0; i < imdH; i++) {
pixWritten = 0;
while (pixWritten < imdW) {
pixCount = *srcPtr++;
- if (pixCount & 0x80) {
- pixCount = (pixCount & 0x7F) + 1;
- // Just to be safe
- pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
- pixWritten += pixCount;
+ if (pixCount & 0x80) { // data
+ pixCount = MIN((pixCount & 0x7F) + 1, imdW - pixWritten);
memcpy(imdVidMem, srcPtr, pixCount);
+
+ pixWritten += pixCount;
imdVidMem += pixCount;
srcPtr += pixCount;
- } else {
+ } else { // "hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
@@ -797,33 +489,45 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
imdVidMemBak += sW;
imdVidMem = imdVidMemBak;
}
- } else if (type == 0x42) { // loc_2AFC4
- warning("=> type == 0x42");
- } else if ((type & 0xF) == 2) { // loc_2AFEC
- warning("=> (type & 0xF) == 2");
- } else { // loc_2B021
- srcPtrBak = srcPtr;
- for (i = 0; i < imdH; i += 2) {
+ } 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) {
- pixCount = (pixCount & 0x7F) + 1;
- // Just to be safe
- pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
- pixWritten += pixCount;
+ 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 {
+ } else { // "hole"
pixCount = (pixCount + 1) % 256;
pixWritten += pixCount;
imdVidMem += pixCount;
}
}
- srcPtrBak += sW + sW;
- srcPtr = srcPtrBak;
+ imdVidMemBak += sW + sW;
+ imdVidMem = imdVidMemBak;
}
}
}
@@ -831,8 +535,8 @@ void ImdPlayer::renderframe(Imd *imdPtr) {
void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
int i;
byte buf[4370];
- int16 chunkLength;
- int16 frameLength;
+ uint16 chunkLength;
+ uint16 frameLength;
uint16 bufPos1;
uint16 bufPos2;
uint16 tmp;
@@ -842,13 +546,16 @@ void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
frameLength = READ_LE_UINT16(src);
src += 4;
- bufPos1 = 4078;
- mode = 0; // 275h (jnz +2)
+
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;
@@ -874,99 +581,644 @@ void ImdPlayer::frameUncompressor(byte *dest, byte *src) {
src += 2;
chunkLength = ((tmp & 0xF00) >> 8) + 3;
- if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0)))
+ if ((mode && ((chunkLength & 0xFF) == 0x12)) ||
+ (!mode && (chunkLength == 0)))
chunkLength = *src++ + 0x12;
bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
- if (((tmp + chunkLength) >= 4096) || ((chunkLength + bufPos1) >= 4096)) {
+ 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;
}
- frameLength -= chunkLength;
- } else if (((tmp + chunkLength) < bufPos1) || ((chunkLength + bufPos1) < bufPos2)) {
+
+ } else if (((tmp + chunkLength) < bufPos1) ||
+ ((chunkLength + bufPos1) < bufPos2)) {
+
memcpy(dest, buf + bufPos2, chunkLength);
- dest += chunkLength;
memmove(buf + bufPos1, buf + bufPos2, chunkLength);
+
+ dest += chunkLength;
bufPos1 += chunkLength;
bufPos2 += chunkLength;
- frameLength -= chunkLength;
+
} else {
+
for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
*dest = buf[bufPos2];
buf[bufPos1] = buf[bufPos2];
}
- frameLength -= chunkLength;
+
}
+ frameLength -= chunkLength;
+
}
}
-void ImdPlayer::play(const char *path, int16 x, int16 y, int16 startFrame, int16 frames,
- bool fade, bool interruptible) {
+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 curFrame;
int endFrame;
- int backFrame;
_vm->_util->setFrameRate(12);
- openImd(path, 0, 0, 0, 0);
- _vm->_video->fillRect(_vm->_draw->_frontSurface, x, y, x + _curImd->width - 1,
- y + _curImd->height - 1, 0);
+ 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 (curFrame = 0; curFrame < endFrame; curFrame++) {
- view(_curImd, curFrame);
- drawFrame(_curImd, curFrame, x, y);
+ 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(_vm->_global->_videoMode);
- if ((interruptible && (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) ||
- _vm->_quitRequested) {
+ _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 (curFrame = _curImd->framesCount - 1; curFrame >= endFrame; curFrame--) {
- for (backFrame = 0; backFrame <= curFrame; backFrame++)
- view(_curImd, backFrame);
- drawFrame(_curImd, curFrame, x, y);
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
- if ((interruptible && (_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B)) ||
- _vm->_quitRequested) {
+ 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();
}
-int16 ImdPlayer::sub_2C825(Imd *imdPtr) {
- warning("GOB2 Stub! sub_2C825()");
- return 0;
+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)
+ 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, (char *) _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;
+
+ 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;
+
+ 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) {
+ char *soundBuf =
+ (char *) (_soundBuffer + _curSoundSlice * _soundSliceSize);
+
+ if (!hasNextCmd)
+ waitEndSoundSlice();
+
+ // Next sound slice data
+ if (cmd == 0xFF00) {
+
+ if (!hasNextCmd && !_noSound) {
+ _vm->_dataIO->readData(imdPtr->handle, soundBuf,
+ _soundSliceSize);
+ _vm->_snd->convToSigned((byte *) 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) {
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) _soundBuffer, dataLength);
+ _vm->_snd->convToSigned(_soundBuffer, dataLength);
+
+ _curSoundSlice = _soundSlicesCount - 1;
+ _soundStage = 1;
+ startSound = true;
+ } else
+ _vm->_dataIO->seekData(imdPtr->handle, dataLength, SEEK_CUR);
+
+ cmd = _vm->_dataIO->readUint16(imdPtr->handle);
+
+ // Clear sound slice
+ } else if (!hasNextCmd && (!_noSound))
+ memset(soundBuf, 0, _soundSliceSize);
+
+ if (!hasNextCmd)
+ _curSoundSlice = (_curSoundSlice + 1) % _soundSlicesCount;
+ }
+
+ // Set palette
+ if (cmd == 0xFFF4) {
+ _vm->_dataIO->seekData(imdPtr->handle, 2, SEEK_CUR);
+ retVal |= 0x10;
+ if (imdPtr->extraPalette) {
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) imdPtr->extraPalette, 768);
+ _vm->_video->setPalette(imdPtr->extraPalette);
+ } else if (imdPtr->palette)
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) imdPtr->palette, 768);
+ else
+ _vm->_dataIO->readData(imdPtr->handle,
+ (char *) _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,
+ (char *) _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, (char *) _frameData, cmd + 2);
+ if (imdPtr->surfDesc)
+ renderFrame(imdPtr);
+
+ retVal |= _frameData[0];
+
+ } else
+ retVal |= 0x800;
+
+ } while (hasNextCmd);
+
+ if (startSound) {
+ _vm->_snd->stopSound(0);
+ _vm->_snd->playSample(_soundDesc, -1, _soundFreq);
+ _soundStage = 2;
+ }
+
+ imdPtr->x = xBak;
+ imdPtr->y = yBak;
+ imdPtr->width = widthBak;
+ imdPtr->height = heightBak;
+
+ imdPtr->curFrame++;
+ if ((imdPtr->curFrame == (imdPtr->framesCount - 1)) && (_soundStage == 2)) {
+ // Clear the remaining sound buffer
+ if (_curSoundSlice > 0)
+ memset(_soundBuffer + _curSoundSlice * _soundSliceSize, 0,
+ _soundSliceSize * _soundSlicesCount -
+ _curSoundSlice * _soundSliceSize);
+
+ _vm->_snd->setRepeating(0);
+ _vm->_snd->waitEndPlay();
+ }
+
+ return retVal;
+}
+
+inline void ImdPlayer::waitEndSoundSlice() {
+ _vm->_video->retrace();
+ _vm->_util->delay(_soundSliceLength);
}
} // End of namespace Gob